Skip to content

fix(cua-driver-rs): CLI 'call' surfaces JSON parse errors with PS5.1 stdin-pipe hint (#1637, closes #1635) - #1642

Merged
f-trycua merged 2 commits into
mainfrom
fix/cli-call-json-parse-and-launch-app-error
May 21, 2026
Merged

fix(cua-driver-rs): CLI 'call' surfaces JSON parse errors with PS5.1 stdin-pipe hint (#1637, closes #1635)#1642
f-trycua merged 2 commits into
mainfrom
fix/cli-call-json-parse-and-launch-app-error

Conversation

@f-trycua

@f-trycua f-trycua commented May 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

cua-driver call <tool> <json> used .and_then(|s| serde_json::from_str(s).ok()).or_else(stdin) which silently swallowed parse errors and fell back to stdin. On PowerShell 5.1, native-command argv parsing mangles multi-field JSON (strips quotes around field names) — the CLI never told the user. The tool's own required-field validator then emitted a misleading "missing field X" error.

Fix

Differentiate "no positional arg" (legit stdin fallback) from "positional arg given but didn't parse" (emit clear error + stdin-pipe hint + exit 2). Applied to both cua-driver call <tool> and the implicit cua-driver <tool> paths.

Sample output after fix:

error: positional JSON arg to 'cua-driver call' did not parse: ...
       received: {pid:9912,window_id:197488}

hint: PowerShell 5.1 strips quotes around JSON field names in
      multi-field args. Pipe the JSON via stdin instead:
        '{"pid":1234,"window_id":5678}' | cua-driver call get_window_state

      Or use PowerShell 7+ (pwsh) which preserves the quotes.

Also closes #1635

The launch_app error "Provide either bundle_id or name" was misleading — Windows resolver accepts aumid, path, launch_path, urls too. The Swift-original message predated those additions. Now reads: "Provide one of: bundle_id, name, aumid, path, launch_path, or urls".

Note: the actual root cause of #1635 (cuademo's cua-driver call launch_app '{"aumid":"..."}' failing) is the PS argv quote-stripping fixed above. The error-message tweak just prevents future confusion when someone hits the error for unrelated reasons.

Closes #1637, closes #1635.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved error handling and diagnostic output when JSON argument parsing fails, now displaying detailed error information and platform-specific hints.
    • Enhanced validation error messages to enumerate all supported application identifier resolver options.

Review Change Stack

…'call' instead of silently falling back to stdin

`cua-driver call <tool> <json>` previously did
`pos.next().and_then(|s| serde_json::from_str(s).ok()).or_else(|| read_stdin_json())`
— the `.ok()` swallowed any parse error and silently fell back to stdin.
On PowerShell 5.1, native-command argv parsing strips quotes around JSON
field names in multi-field args (`'{"a":1,"b":2}'` arrives as `{a:1,b:2}`
which serde_json rejects). The fall-through reads from empty stdin →
tool sees `args = null` → emits a misleading "missing required field X"
error instead of the actual cause.

## Repro

PowerShell 5.1 (Windows 11 24H2):
```
PS> cua-driver call get_window_state '{"pid":9912,"window_id":197488}'
cua-driver.exe : Missing required integer field pid.
```

The JSON is fine; PS 5.1's argv parser mangled it. CLI silently absorbed
the parse failure.

After this PR:
```
PS> cua-driver call get_window_state '{"pid":9912,"window_id":197488}'
error: positional JSON arg to 'cua-driver call' did not parse: ...
       received: {pid:9912,window_id:197488}

hint: PowerShell 5.1 strips quotes around JSON field names in
      multi-field args. Pipe the JSON via stdin instead:
        '{"pid":1234,"window_id":5678}' | cua-driver call get_window_state

      Or use PowerShell 7+ (pwsh) which preserves the quotes.
```

Exit code 2 instead of silent failure with a downstream misleading error.

## Implementation

`crates/cua-driver/src/cli.rs`: replace `.and_then(...).or_else(...)`
with explicit `match` that differentiates "no positional arg" (fall back
to stdin) from "positional arg given but didn't parse" (emit clear error
+ stdin-pipe hint + exit 2). Applied to both the explicit `call`
subcommand path and the implicit `cua-driver <tool> <json>` path.

## Bonus: launch_app error message

The Swift-original error "Provide either bundle_id or name to identify
the app to launch." predated the Windows aumid/path/launch_path/urls
additions and made #1635 look like an aumid-specific bug. Updated to
"Provide one of: bundle_id, name, aumid, path, launch_path, or urls".
The actual cause of #1635 was the PS argv quote-stripping above; the
improved message just stops misleading anyone who hits the error for
unrelated reasons.

Closes #1637, closes #1635.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@vercel

vercel Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Preview May 21, 2026 6:11pm

Request Review

@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: edac5a10-3099-4f88-bdfd-c4b9f6ddc31f

📥 Commits

Reviewing files that changed from the base of the PR and between d695d3f and 839b5a0.

📒 Files selected for processing (2)
  • libs/cua-driver-rs/crates/cua-driver/src/cli.rs
  • libs/cua-driver-rs/crates/platform-windows/src/tools/impl_.rs

📝 Walkthrough

Walkthrough

The PR improves error handling in the CLI and validation messages. JSON argument parsing in parse_command() now distinguishes between missing positional arguments (fallback to stdin) and malformed JSON (emit diagnostics and exit code 2). The launch_app error message is expanded to list all supported resolver fields instead of a subset.

Changes

CLI Error Handling and Field Validation Messages

Layer / File(s) Summary
JSON parse failure detection in explicit call and implicit shorthand paths
libs/cua-driver-rs/crates/cua-driver/src/cli.rs
Both the explicit call subcommand and implicit <tool> shorthand parsing now explicitly handle JSON parse failures: invalid positional JSON is rejected with detailed diagnostics and exit code 2, while missing positional JSON correctly falls back to read_stdin_json().
Expanded error message for missing app identifier fields
libs/cua-driver-rs/crates/platform-windows/src/tools/impl_.rs
The launch_app validation error when no app identifier is provided now enumerates all supported resolver fields (bundle_id, name, aumid, path, launch_path, urls) instead of only two legacy fields.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • trycua/cua#1544: Both PRs modify the LaunchAppTool app resolver validation in impl_.rs—this PR updates the error message to list all supported fields, while that PR extends the resolver to route through the aumid field for packaged-app launches.

Poem

🐰 The CLI now speaks with clarity bright,
When JSON goes wonky, no silent night!
Parse failures gleam in PowerShell's light,
While launch_app lists fields, all fields, all right! ✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/cli-call-json-parse-and-launch-app-error

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.

…ion all valid fields (#1635)

Companion to the cli.rs fix in this PR. The Swift-original error message
("Provide either bundle_id or name") predated the Windows-specific
additions to LaunchAppTool's resolver chain (aumid, path, launch_path,
urls) and made #1635 look like an aumid-specific deserialization bug.

The actual root cause of #1635 was the PS argv quote-stripping fixed by
this PR's cli.rs change. The improved error message is defense-in-depth:
if a user hits the missing-target case for unrelated reasons (e.g.
empty args via stdin or a script that builds the JSON wrong), they get
a list of every accepted field, not just the Swift-era subset.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@f-trycua
f-trycua merged commit 3b0f3ab into main May 21, 2026
4 of 5 checks passed
@f-trycua
f-trycua deleted the fix/cli-call-json-parse-and-launch-app-error branch May 21, 2026 18:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant