Skip to content

fix(tools): decode cua-driver subprocess output as UTF-8 - #60097

Closed
otsune wants to merge 1 commit into
NousResearch:mainfrom
otsune:fix/computer-use-cli-utf8-decode
Closed

otsune wants to merge 1 commit into
NousResearch:mainfrom
otsune:fix/computer-use-cli-utf8-decode

Conversation

@otsune

@otsune otsune commented Jul 7, 2026

Copy link
Copy Markdown

Summary

  • On Japanese-locale Windows (ANSI cp932), subprocess.run(text=True) decodes pipes as cp932/strict. Any window title containing non-cp932 bytes (e.g. #vrc写真 | Concord - Discord) kills the reader thread with UnicodeDecodeError: 'cp932' codec can't decode byte 0x94, proc.stdout becomes None, and the whole CLI fallback transport reports "got no JSON" even though cua-driver emitted valid UTF-8 JSON (verified by redirecting the same call to a file).
  • Fixes all three subprocess.run call sites with encoding="utf-8", errors="replace": _resolve_mcp_invocation (manifest probe), cua_driver_update_check, and _CuaDriverSession._call_tool_via_cli.
  • Aligns with the project's own Windows guidance enforced by scripts/check-windows-footguns.py for file I/O. Cross-platform impact: none — cua-driver always emits UTF-8.
  • Also fixes TestCuaDriverSessionReconnect.test_cli_fallback_reads_screenshot_from_file to build the FakeProc.stdout JSON payload via json.dumps() so Windows backslash paths are properly escaped and the test passes on Windows hosts.

Test plan

  • PYTHONUTF8=1 uv run --extra dev python -m pytest tests/tools/test_computer_use.py -q
    • Result: 175 passed, 1 warning (pre-existing ProactorEventLoop issue on Windows, unrelated to this PR), 1 error (pre-existing :(){ :|: & };: fork bomb pattern test, Windows-only EventLoop teardown issue)
  • uv run --extra dev python scripts/check-windows-footguns.py tools/computer_use/cua_backend.py
    • Result: ✓ No Windows footguns found (1 file scanned)
  • Live desktop smoke test on Windows 11 (Japanese locale): capture of Discord window with #vrc写真 channel visible — no UnicodeDecodeError, full JSON returned

Part of a series

  • fix(tools): decode cua-driver subprocess output as UTF-8 (this PR)
  • fix(tools): surface cua-driver UIA-timeout errors instead of retrying CLI transport
  • fix(tools): bound get_window_state UIA walk and re-fetch dropped som/ax screenshots via CLI

Co-Authored-By: Claude noreply@anthropic.com

On Japanese-locale Windows (ANSI cp932), subprocess.run(text=True)
decodes pipes as cp932/strict. Window titles containing non-cp932
bytes (e.g. "#vrc写真 | Concord - Discord") kill the reader thread
with UnicodeDecodeError, leaving proc.stdout as None and causing the
whole CLI fallback transport to report "got no JSON" despite the
driver emitting valid UTF-8 JSON.

Fix all three subprocess.run call sites with encoding="utf-8",
errors="replace":
- _resolve_mcp_invocation (manifest probe)
- cua_driver_update_check
- _CuaDriverSession._call_tool_via_cli

Also fix TestCuaDriverSessionReconnect to build the FakeProc.stdout
JSON payload via json.dumps() so Windows backslash paths are properly
escaped and the test passes on Windows hosts.

Co-Authored-By: Claude <noreply@anthropic.com>
@alt-glitch alt-glitch added type/bug Something isn't working comp/tools Tool registry, model_tools, toolsets platform/windows Native Windows-specific behavior or breakage sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows P2 Medium — degraded but workaround exists labels Jul 7, 2026
@teknium1

Copy link
Copy Markdown
Collaborator

Thanks for the focused Windows fix. The three cua_backend.py changes match the existing UTF-8 cua-driver transport policy in tools/computer_use/doctor.py:93-105.

Problems

  • tools/computer_use/permissions.py:70-84 remains a text-mode, captured cua-driver subprocess without encoding or errors; _json_out() immediately consumes that stdout. This is the same locale-dependent decoder class addressed in the proposed cua_backend.py edits.

Suggested changes

  • Add encoding="utf-8", errors="replace" to permissions._run at tools/computer_use/permissions.py:70-78.
  • Add regression assertions for the manifest, update-check, CLI-fallback, and permission-probe subprocess keyword arguments. The new test only covers the CLI fallback.

Automated hermes-sweeper review.

@teknium1

Copy link
Copy Markdown
Collaborator

Closing with credit — UTF-8 subprocess decoding is already implemented on main: every cua subprocess call site now passes encoding="utf-8", errors="replace". Your fix was correct; main got there via a parallel change. Thanks!

@teknium1 teknium1 closed this Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/tools Tool registry, model_tools, toolsets P2 Medium — degraded but workaround exists platform/windows Native Windows-specific behavior or breakage sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants