Skip to content

Fix run_tests array params double-encoding when client sends JSON-str… - #695

Closed
voonfoo wants to merge 2 commits into
CoplayDev:betafrom
voonfoo:fix/run-tests-array-double-encoding
Closed

Fix run_tests array params double-encoding when client sends JSON-str…#695
voonfoo wants to merge 2 commits into
CoplayDev:betafrom
voonfoo:fix/run-tests-array-double-encoding

Conversation

@voonfoo

@voonfoo voonfoo commented Feb 7, 2026

Copy link
Copy Markdown
Contributor

Description

Fix run_tests array parameter filtering (test_names, group_names, category_names, assembly_names) returning zero matching tests due to double-encoding.

Type of Change

Save your change type

  • Bug fix (non-breaking change that fixes an issue)

Changes Made

  • Updated _coerce_string_list in Server/src/services/tools/run_tests.py to detect and parse JSON-stringified arrays before forwarding to Unity
  • When FastMCP/Pydantic coerces a list[str] | str union parameter to str, it produces '["test1"]' instead of a native list. The helper now parses these back to a proper list[str]

Testing/Screenshots/Recordings

Debug logs on the C# side confirmed the double-encoding:

Before (broken):
{"testNames":["[\"Namespace.Test1\"]"]}
Unity receives the literal string ["Namespace.Test1"] as the test name — matches nothing, returns 0 tests.

After (fixed):
{"testNames":["Namespace.Test1"]}
Unity correctly matches and runs targeted tests correctly.

Summary by Sourcery

Bug Fixes:

  • Ensure JSON-stringified arrays passed as string values to run_tests are parsed into proper string lists before being forwarded to Unity.

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced input validation to robustly handle various string formats, including whitespace trimming and array parsing, improving test configuration reliability.
…ingified lists

When MCP clients send array parameters like test_names as JSON arrays,
FastMCP/Pydantic can coerce list[str] | str union types to the str
variant, producing a JSON-stringified array (e.g. '["test1"]') instead
of a native list. _coerce_string_list then wraps this string as
['["test1"]'], causing Unity's test filter to receive the literal string
'["test1"]' instead of 'test1' — matching zero tests.

The fix detects JSON-stringified arrays in the str branch and parses
them back to a proper list before forwarding to Unity.
@sourcery-ai

sourcery-ai Bot commented Feb 7, 2026

Copy link
Copy Markdown
Contributor
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adjusts run_tests string list coercion to correctly handle JSON-stringified arrays, preventing double-encoded test filters from resulting in zero matches.

File-Level Changes

Change Details Files
Improve string-to-list coercion for run_tests filter parameters to handle JSON-stringified arrays and ignore empty values.
  • Return None for empty or whitespace-only string inputs instead of a single empty string element.
  • Detect inputs that look like JSON arrays (starting with '[') and attempt to json.loads them.
  • If JSON parsing succeeds and yields a list, normalize each element to a stripped string and drop falsy/blank entries, returning None if the resulting list is empty.
  • Gracefully fall back to treating the original value as a single string element if JSON parsing fails or does not yield a list.
  • Preserve existing behavior for list inputs by normalizing elements to stripped strings and dropping falsy/blank entries.
Server/src/services/tools/run_tests.py

Possibly linked issues

  • #run_tests test filtering broken: snake_case params ignored + double-serialized arrays: Link: PR fixes the described double-serialized array bug causing run_tests filters to match zero tests.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Feb 7, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The _coerce_string_list function in run_tests.py was made more robust: it returns None for whitespace-only strings, attempts to parse JSON array strings into trimmed non-empty lists, falls back to single-element trimmed lists for plain strings, and preserves existing list handling.

Changes

Cohort / File(s) Summary
String Parsing Enhancement
Server/src/services/tools/run_tests.py
Refined _coerce_string_list: treat whitespace-only input as None; parse JSON array strings into trimmed lists (log on JSON errors); convert non-JSON trimmed strings into single-item lists; filter falsy/empty items from lists.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

I’m a rabbit tidying strings with glee,
Trimming, parsing arrays, setting empties free,
A JSON hop, a whitespace skip,
One-item lists from a single blip,
Hooray for clean inputs — hop, hop, whee! 🐰✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: fixing double-encoding of array parameters in run_tests when clients send JSON-stringified data.
Description check ✅ Passed The description covers the required sections: description of the bug, type of change (bug fix), specific changes made, testing/verification with before/after logs, and additional context. All essential information is present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • Consider moving the json import to the module level instead of importing inside _coerce_string_list to avoid repeated imports on hot paths.
  • The JSON detection currently only checks stripped.startswith("["); you might also guard with stripped.endswith("]") or a more explicit heuristic to avoid accidentally treating non-JSON strings that start with [ as lists.
  • When JSON parsing fails you silently fall back to treating the value as a scalar string; if this is unexpected input, you may want to at least log at debug level to make future mis-encodings easier to diagnose.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider moving the `json` import to the module level instead of importing inside `_coerce_string_list` to avoid repeated imports on hot paths.
- The JSON detection currently only checks `stripped.startswith("[")`; you might also guard with `stripped.endswith("]")` or a more explicit heuristic to avoid accidentally treating non-JSON strings that start with `[` as lists.
- When JSON parsing fails you silently fall back to treating the value as a scalar string; if this is unexpected input, you may want to at least log at debug level to make future mis-encodings easier to diagnose.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
…ug logging

- Move json import to module level to avoid repeated imports
- Guard JSON detection with both startswith("[") and endswith("]")
- Log at debug level when JSON parsing fails for easier diagnostics
@voonfoo

voonfoo commented Feb 7, 2026

Copy link
Copy Markdown
Contributor Author

duplicated PR #690, will close this

@voonfoo voonfoo closed this Feb 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant