Stray "call"/"court" token before tool calls; internal <invoke> XML printed as text instead of executing (Windows local + cloud Cowork)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Occasionally, instead of cleanly executing a tool call, Claude Code emits a stray plain-text token — "call" or "court" — and then prints its internal tool-call markup (<invoke name="..."><parameter ...>...</parameter></invoke>) to the user as literal text. The call does not run. Re-issuing the request usually works and no files are corrupted, so the harm is garbled output and an interrupted workflow rather than data loss.
What Should Happen?
The tool call should execute normally: no stray "call"/"court" token should appear, and the internal <invoke> markup should never be shown to the user as text. The action should run on the first attempt.
Error Messages/Logs
# Verbatim leak (cloud Cowork session, tool mcp__workspace__bash). The stray
# token (call / court) is emitted as plain text, immediately followed by the
# internal <invoke> XML rendered literally instead of executing. The block also repeats.
call
<invoke name="mcp__workspace__bash">
<parameter name="command">cd "/sessions/zen-inspiring-knuth/mnt/English Master Project" && grep -c "이미지키 ↔ AI회화 키 분리 상태" docs/ops/할일_리스트_마스터.md</parameter>
</invoke>
court
<invoke name="mcp__workspace__bash">
<parameter name="command">cd "/sessions/zen-inspiring-knuth/mnt/English Master Project" && grep -c "이미지키 ↔ AI회화 키 분리 상태" docs/ops/할일_리스트_마스터.md</parameter>
</invoke>
court
<invoke name="mcp__workspace__bash">
<parameter name="command">cd "/sessions/zen-inspiring-knuth/mnt/English Master Project" && bash tools/release_check.sh 2>&1 | tail -5</parameter>
</invoke>
Steps to Reproduce
Note: This is intermittent and not reliably reproducible on demand. It is not tied to any specific file or command — it appears to be triggered by model output formatting, not by a user action. Below is the pattern under which it has consistently appeared:
- Open a Claude Code session and work normally, issuing many tool calls over an extended session (it clusters later in long, tool-call-heavy sessions).
- Before a tool call, the model emits a stray plain-text token — "call" or "court" — instead of cleanly invoking the tool.
- The harness rejects the malformed call, and the model's internal <invoke name="..."> ... </invoke> XML is printed to the user as literal text instead of being executed.
- The same tool-call block is often emitted twice (repeated).
- Re-running the request usually succeeds; no files are corrupted. The impact is garbled output and an interrupted workflow, not data loss.
Observed across two independent environments (see Additional Information), which suggests the cause is model-side rather than environment-specific.
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
Claude 1.12603.1.0
Platform
Other
Operating System
Windows
Terminal/Shell
PowerShell
Additional Information
This is not specific to one machine or OS. The same behavior — a stray "call"/"court" token followed by the internal <invoke> XML being printed as text instead of executing — has appeared in two independent environments:
- Local: Claude Code on Windows 11 (PowerShell).
- Cloud: a Claude "Cowork" sandbox session (Linux), with the leaked block referencing mcp__workspace__bash and a /sessions/.../mnt/ path.
It has also been seen on more than one model (Fable and Opus). Because it spans different OSes, environments, and models, the cause appears to be model-side output formatting rather than any local setup.
It is intermittent — the large majority of tool calls are clean — and it tends to cluster later in long, tool-call-heavy sessions. Re-running the request normally succeeds and no files are corrupted. Screenshots attached.
Showing cached comments. Read the full discussion on GitHub ↗
7 Comments
I have seen this too. Macos. Very rare for me, but not one off
Adding a more severe variant of this "court" / corrupted-tool-call behavior, on a newer version + Windows.
What I saw
Same root pattern (the tool-call opener token gets corrupted to
court), but in my session it didn't stop at a single malformed<invoke>block — thecourttoken went into a full decode loop. The assistant turn started with a normal, on-task paragraph (it was about to run a CLI command after some explanatory prose), then emitted:repeated 12,831 times in a single turn (13,362 across the whole session). There was no trailing
<invoke>XML in my case — just the barecourttoken looping.stop_reasonwasnull, so it never reached a stop token and the turn was truncated mid-loop.Trigger matches the existing reports
Environment
This is newer than the earlier reports (2.1.143 / 2.1.165), so it persists across versions, and across macOS + Windows — consistent with this being model-side rather than environment-specific.
Workaround
Don't
--resumethe corrupted session — reloading the ~13k-tokencourtcontext tends to re-trigger the loop. Archive/rename the session.jsonl, start fresh, and re-seed only the last coherent state.Confirming the same behavior on macOS (so this now spans Windows + Linux + macOS), with Opus in Claude Code, during a long tool-call-heavy session.
Symptoms matched exactly:
courtin my case) right before the tool call<invoke ...>XML printed as literal text instead of executingOne observation that may help narrow it down: it tended to appear on turns where the model wrote prose immediately before emitting the tool call (explain-then-call in the same turn). Splitting "explain" and "call" into separate turns noticeably lowered the frequency, but did NOT eliminate it — so the root cause does look model-side, as noted.
Adding a data point from the Claude in Chrome MCP / browser-automation path — most reports here are Edit/Read/Bash/CLI, and the browser-MCP angle surfaces two consequences that don't seem captured yet.
Env: Windows 11, Claude Code hosted inside Claude Desktop (Cowork / local-agent mode), model
claude-opus-4-8, browser automation via theClaude in ChromeMCP (cloud-relay peer path). Same trigger profile as above — long, tool-call-heavy session, and the corruption landed on turns that wrote explanatory prose right before the intended tool call (the "explain-then-call" correlation from #60584 / #66153 and the macOS comment above).1. Silent stall, not just garbled text. When the stray
court+ a bare<invoke name="mcp__Claude_in_Chrome__computer">(noantml:prefix) is emitted as text, the click/type never fires. With no parse error surfaced to the user — just un-executed text — the browser automation appears to hang mid-flow. It's easily misdiagnosed as a relay/connection problem rather than tool-call corruption; that cost me a while before I spotted thecourttoken.2. Recirculation loop (history + clipboard). The malformed block gets carried back into context and reappears on later turns as if it were input; the model then sometimes continues the broken narration, so the corruption is self-reinforcing — consistent with the in-context few-shot poisoning in #62344 and with the "don't
--resumethe corrupted session" advice above. In my case it also landed on the OS clipboard (the flow used the clipboard for field operations), giving it a second re-injection carrier. Clearing the clipboard alone did not stop it — the conversation-history echo was the primary channel.Workarounds that worked: clear the OS clipboard (removes one carrier); start a fresh session /
/clearand don't resume the poisoned context; restart the host (reinitializes the Cowork relay) — most reliable; or switch to the standalone CLI route (local native-host pipe, no cloud relay), which avoided it for me.Net: looks like the same model-side token-generation defect, but on the browser-MCP path it turns "garbled output" into a silent automation stall plus a self-reinforcing loop.
We've been running a Stop-hook auto-recovery for this in production (Windows, Opus 4.8 1M) and came to share it — only to find @TheGreatCBH had already posted a nearly identical Stop-hook approach early on, over on the canonical issue #49747 (with a published repo). That's the good side of community echo: independently landing on the same fix is a decent signal it's the right shape. Sharing ours in the Windows thread anyway, since it differs in a couple of ways that matter for tool-heavy / multi-agent sessions.
Environment
Why a Stop hook and not
PreToolUse: a leaked call never becomes atool_use, soPreToolUsenever fires. The hook inspects the last assistant message at turn end; if it finds leaked tool-call markup itblocks the stop with areasonthat tells the model to re-issue the call correctly. Thereasoncomes back as a system reminder and the model retries.What's different in this one
tool_useis present in the same turn. In tool-heavy turns sometimes only some of several calls leak; gating on "no tool_use this turn" misses those.Plus
MAX_RETRY=5, and on giving up it keeps the per-session counter so it stops blocking that episode (no infinite block) and thereasonrecommends a fresh session — because once the context is poisoned (#62344) retries just reproduce the same malformed output.Hook —
~/.claude/hooks/stop-hook-toolcall-leak-retry.sh:Add it to the
Stoparray in~/.claude/settings.json:This is a stopgap, not a fix — remove it once the regression is resolved. Hope it helps the Windows folks here.
Also reproducing this on Claude Code VS Code extension 2.1.197 (Windows 11), same stray-token pattern (observed both "course" and "court") appearing immediately before
<invoke>and rendered as literal text instead of executing.Two additional data points that differ from the pattern described above:
Both points are consistent with #66247's finding that this is a client-side
tool_usestreaming/parsing regression rather than a context-length or model-specific issue.Adding a data point that may help narrow down reproduction conditions.
Environment: macOS, Cowork/Claude Code CLI sessions (mix of Sonnet/Opus).
Pattern observed across multiple long sessions over ~2 weeks: the stray token before
<invoke>was consistently one of a small set of short words/phrases —call,course,court, or a Korean prefix word (e.g. "여기"/"이제"/"다음") — placed immediately before the tool-call block in the assistant's own narration. Once it happened once in a session, it tended to recur multiple times in that same session (observed 3–10+ recurrences in a single session on different occasions), suggesting some form of local pattern reinforcement rather than a one-off sampling fluke.Worst observed case — runaway repetition: in one session, once the model started emitting
courtas the stray prefix, it did not self-correct or stop. Left unattended, it repeated the samecourt+ leaked<invoke>pattern hundreds of times in a row in a single response, burning a large number of tokens with zero successful tool executions, until the user manually interrupted it. This suggests that once the model enters this failure mode, it can get stuck in a self-reinforcing loop rather than recovering after one or two occurrences — the loop itself seems to need external interruption to break.**What did not help:** adding explicit system/CLAUDE.md-level instructions telling the model never to type a prefix word before a tool call, and to end narration with a period before emitting the tool-call block. This was tried repeatedly across sessions and the issue still recurred — consistent with this being a harness/parsing-layer issue rather than something promptable away from the model side.
What did help: simply retrying — re-emitting the tool call — after noticing the block leaked as plain text with no corresponding tool_result. No data loss observed, just wasted turns/tokens.
No root cause insight to add beyond what's already here, but wanted to confirm this reproduces consistently across environments/models and that prompt-level mitigation doesn't fix it, in case that's useful for isolating whether it's a streaming/parsing issue in the harness.