Skip to content

fix: PowerShell exec output with BOM renders as text#109163

Open
TianT1209 wants to merge 1 commit into
openclaw:mainfrom
TianT1209:fix/issue-108802
Open

fix: PowerShell exec output with BOM renders as text#109163
TianT1209 wants to merge 1 commit into
openclaw:mainfrom
TianT1209:fix/issue-108802

Conversation

@TianT1209

@TianT1209 TianT1209 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

AI-assisted: yes

Closes #108802

What Problem This Solves

Fixes an issue where users running exec on Windows would see BOM-prefixed PowerShell output render as unreadable output or attachment-like text instead of normal text.

Why This Change Was Made

Windows subprocess output now checks for UTF-8, UTF-16LE, and UTF-16BE BOMs before falling back to the existing UTF-8 / console-code-page path. The streaming decoder also waits for enough leading bytes to resolve split BOM chunks.

User Impact

PowerShell commands that emit BOM-prefixed text now stay readable in the agent context instead of degrading into corrupted output.

Evidence

  • node scripts/run-vitest.mjs src/infra/windows-encoding.test.ts - passed, 13 tests
  • node_modules\.bin\oxlint.cmd src/infra/windows-encoding.ts src/infra/windows-encoding.test.ts - passed
  • git diff --check - passed
  • PR branch rebased onto latest upstream/main; the previous check-dependencies unused-export failures were already fixed on current main
  • Local pnpm deadcode:full proof blocked by local Node 24.13.0; current OpenClaw requires Node >=24.15.0, while GitHub CI uses Node 24.18.0
  • Fresh local autoreview blocked before model review because local Git 2.21 does not support the helper's --end-of-options argument

Native Windows exec-path proof:

Command shape: node_modules\.bin\tsx.cmd -e "<script>" imported createChildAdapter from src/process/supervisor/adapters/child.ts, launched powershell.exe -NoLogo -NoProfile -NonInteractive -Command "[Console]::OpenStandardOutput().Write(...)", and wrote BOM-prefixed bytes directly to stdout.

utf8: {"code":0,"stdout":"hello\n","stderr":""}
utf16le: {"code":0,"stdout":"hello\n","stderr":""}
utf16be: {"code":0,"stdout":"hello\n","stderr":""}

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. labels Jul 16, 2026
@clawsweeper

clawsweeper Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 16, 2026, 9:57 PM ET / July 17, 2026, 01:57 UTC.

Summary
The PR adds BOM-aware UTF-8, UTF-16LE, and UTF-16BE decoding to shared Windows subprocess output handling, including split-BOM streaming coverage.

PR surface: Source +92, Tests +55. Total +147 across 2 files.

Reproducibility: yes. at the source-and-transcript level: BOM-prefixed PowerShell stdout follows the shared Windows decoder path, and the PR body shows native Windows results for all three BOM forms. This review did not independently execute Windows.

Review metrics: none identified.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #108802
Summary: This PR is the direct candidate fix for the linked Windows BOM exec-output issue.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Risk before merge

  • [P1] The PR head is behind current main, so maintainers should refresh the merge result or rebase before landing; no concrete three-way-merge regression is currently shown.

Maintainer options:

  1. Decide the mitigation before merge
    Refresh the branch against current main, retain BOM precedence over UTF-8 and console-code-page fallback, and land the shared decoder change with the split-chunk regression tests.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • No automated repair is indicated; after refreshing the stale base, this PR is ready for ordinary maintainer review.

Security
Cleared: The patch changes text decoding and focused tests without adding dependencies, permissions, secret access, workflows, downloads, or executable supply-chain inputs.

Review details

Best possible solution:

Refresh the branch against current main, retain BOM precedence over UTF-8 and console-code-page fallback, and land the shared decoder change with the split-chunk regression tests.

Do we have a high-confidence way to reproduce the issue?

Yes at the source-and-transcript level: BOM-prefixed PowerShell stdout follows the shared Windows decoder path, and the PR body shows native Windows results for all three BOM forms. This review did not independently execute Windows.

Is this the best way to solve the issue?

Yes; BOM sniffing in the existing shared Windows decoder is narrower and more maintainable than changing attachment classification or adding a configuration surface.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 6b6bf3a34bd3.

Label changes

Label justifications:

  • P2: This is a bounded Windows exec-output correctness fix with limited platform-specific blast radius.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The updated PR body contains after-fix native Windows live output showing readable UTF-8, UTF-16LE, and UTF-16BE BOM-prefixed stdout through the real child-process adapter.
  • proof: sufficient: Contributor real behavior proof is sufficient. The updated PR body contains after-fix native Windows live output showing readable UTF-8, UTF-16LE, and UTF-16BE BOM-prefixed stdout through the real child-process adapter.
Evidence reviewed

PR surface:

Source +92, Tests +55. Total +147 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 124 32 +92
Tests 1 55 0 +55
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 179 32 +147

What I checked:

  • Current-main gap: The existing Windows fallback path performs UTF-8 and console-code-page decoding but has no BOM-specific decode step; the PR inserts BOM detection before those fallbacks. (src/infra/windows-encoding.ts:132, 6b6bf3a34bd3)
  • Shared execution boundary: Windows subprocess stdout and stderr are decoded through the shared process-output path, so fixing the decoder addresses the observable exec behavior without changing attachment classification. (src/process/exec.ts:68, 6b6bf3a34bd3)
  • Focused regression coverage: The branch adds buffer tests for all three supported BOMs and a streaming test where the UTF-16LE BOM is split across chunks. (src/infra/windows-encoding.test.ts:111, c7092fa53da4)
  • Native Windows proof: The updated PR body records an after-fix Windows child-adapter run that launches PowerShell and returns readable hello output for UTF-8, UTF-16LE, and UTF-16BE BOM-prefixed bytes. (src/process/supervisor/adapters/child.ts, c7092fa53da4)
  • Decoder dependency contract: Node TextDecoder supports UTF-8, UTF-16LE, and UTF-16BE, removes their BOM by default, and supports fragmented streaming input.
  • Feature provenance: The shared Windows code-page-aware subprocess decoding behavior dates to the work tracked by fix: use TextDecoder for proper GBK encoding support on Windows #56538 and was documented in the 2026.4.27 release line; this PR extends that same owner boundary rather than creating a parallel decoder. (CHANGELOG.md)

Likely related people:

  • vincentkoc: Recent shipped Windows command-discovery and installer-runtime fixes make this the strongest available routing signal for a Windows process-output follow-up, though direct blame on the central decoder path was unavailable. (role: recent adjacent Windows runtime contributor; confidence: low; commits: 72b9bc7, 1252378; files: src/infra/windows-encoding.ts, src/process/exec.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (2 earlier review cycles)
  • reviewed 2026-07-16T16:31:42.672Z sha be9d0ae :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-17T01:15:30.814Z sha c7092fa :: needs maintainer review before merge. :: none

@TianT1209

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: M status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

exec tool renders PowerShell output as "see in attachment" on Windows when output contains binary BOM

1 participant