Tool calls intermittently emitted as literal text instead of being executed — silent task stalls on Opus 4.8 / Sonnet 4.6

Open 💬 0 comments Opened Jun 29, 2026 by himuroo

(Note: I'm intentionally not pasting the literal tool-invocation markup below, because its presence in text appears to help induce this very bug. A redacted screenshot is available on request.)

Summary

In Claude Code, a tool call (Read, Bash, WebSearch, Edit, etc.) is occasionally not executed. Instead, the assistant emits the opening tool-invocation markup as plain text inside its message, immediately prefixed by a short word that always begins with the letter "c" (most often "call", "count", or "court"). When this happens the harness does not run the tool. In the most common variant the model then reports normal completion (stop_reason: "end_turn"), so the harness detects nothing wrong and the turn ends silently — the user believes the work was done when nothing executed.

Evidence below comes from my own local Claude Code logs (48 sessions including subagent logs, ~60,000 JSONL lines). Figures are deliberately conservative.

Quantitative data

Rate = affected assistant messages ÷ total assistant messages for that model, across all my sessions. (The denominator is all assistant turns, not only tool-calling turns, so the true rate per tool-calling turn is higher than shown.)

| Model | Affected | Total assistant msgs | Rate |
|---|---:|---:|---:|
| Opus 4.8 | 249 | 26,708 | 0.93% |
| Sonnet 4.6 | 6 | 859 | 0.70% |
| Opus 4.7 | 0 | 890 | 0% |
| Haiku 4.5 | 0 | 336 | 0% |

  • 255 affected assistant messages in total. Of these, 102 were complete stalls (no concurrent valid tool call): stop_reason: "end_turn" ×74, null ×28. The remaining 153 also carried a valid concurrent tool call, so the turn continued but with spurious text.
  • Consistent across Claude Code versions 2.1.165–2.1.187 — not a single-build regression.
  • Occurs in both the main agent and subagents.
  • Affects every tool type observed (WebFetch, WebSearch, Bash, Read, Edit, Write, Task/Agent).
  • The text-ified invocation is preceded by a word that always begins with "c". Most common preceding tokens: call (77), count (73), court (47), course (7), case (3) — these counts exclude one session in which the markup was already present in the prompt. A control/start token for a tool call surfacing as a plain "c…" word is the clearest signal and may be worth investigating as a specific decoding/tokenization issue.

Two failure modes

  • Mode B — silent pass-through (the more harmful variant; main agent; 74 complete stalls, stop_reason: "end_turn"). The model writes the text-ified invocation, then self-reports normal completion. The harness sees no anomaly and ends the turn. This is the user-visible "the task just stopped" — caught only when a human notices nothing ran.
  • Mode A — malformed-and-retry (primarily subagents; 28 cases, stop_reason: null). The harness flags the output as a malformed/un-parseable tool call and auto-retries. Retries sometimes succeed but can re-trigger the same "c…" corruption on the next attempt (chaining). Note: I also observed a subagent that did not auto-retry and instead returned "completed" with the text-ified call — so auto-retry is not guaranteed even for subagents.

Reproduction conditions (observed; not a deterministic repro)

  • Concentrated at the moment of receiving a tool result and issuing the next tool call.
  • More frequent under heavy context (long sessions; immediately after a large prompt).
  • Newer models only in my data (Opus 4.8, Sonnet 4.6); 0 occurrences on Opus 4.7 and Haiku 4.5.
  • Aggravating factors (not root cause): (a) the literal invocation markup already being present in the conversation or a file appears to invite mimicry — contributed to ~73 of 255 cases, but 182 (71%) occurred with no such markup in user input; (b) parallel tool calls — but single tool calls were the majority (139), so parallelism is not the cause.

Impact

  • Silent, undetected task interruption (Mode B): the user must manually notice that nothing executed and re-request, every time. This undermines trust in long-running or autonomous workflows.
  • For subagents, auto-retry mitigates but does not eliminate it, and can chain.
  • At ~1% of assistant turns on the current default models, this is frequent enough to be a recurring operational cost in real work.

Requests

  1. Investigate the generation/decoding behavior that causes a tool-call start to surface as a plain "c…" word on Opus 4.8 / Sonnet 4.6.
  2. Add a harness-side guard: detect an assistant message that contains tool-invocation markup as text and treat it as a malformed tool call (retry), rather than passing it through as a normal end_turn. This would close Mode B (the silent variant) even before the model-side cause is fixed.
  3. Confirm whether this is a known regression associated with newer models or with Claude Code 2.1.165–2.1.187.

Environment

  • Claude Code 2.1.165–2.1.187, macOS (darwin 24.2.0).
  • Models affected: Opus 4.8, Sonnet 4.6.
  • Evidence is aggregate counts only; no conversation content included. Redacted examples or the analysis method available on request.

View original on GitHub ↗