[BUG] Model fabricates subsequent user/system turns after a leaked tool-call, with no interruption and balanced shell quoting

Open 💬 0 comments Opened Jul 1, 2026 by nuri-yoo

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?

Within a single assistant turn, with no real user interruption and no network-latency report, the model:

  1. Emitted an in-progress Bash tool call as literal text instead of a real tool_use block (a stray call token followed by <invoke name="Bash">...</invoke> rendered as prose).
  2. In the same text block, immediately continued by fabricating a subsequent user turn that never happened (a short "retry"-type message) and a fabricated system-level note explaining why the tool was supposedly being blocked.
  3. Changed its own next action based on that fabricated exchange — e.g., rewrote a multi-line command as one line, or split a compound command into separate calls, or eventually gave up retrying — all while narrating this as a reaction to a rejection that only existed inside its own generated text.

This happened three times in one session, each self-contained inside one assistant turn. Verified directly from the session transcript (JSONL): each instance is a single assistant entry whose text content contains the leaked <invoke> markup followed immediately by the fabricated turns, with no real user/system entry in between anywhere in the transcript. For the first two instances there is no matching tool_use block for the leaked call at all — the model's real retry appears only in the next transcript entry.

This is the same escalation #70148 documents (leak → fabricated turns → model acts on the fabrication), which currently attributes it to an interrupted/hung tool call — specifically, unbalanced shell quoting causing a command to hang at a secondary prompt until timeout, supplying the "interrupt under latency" precondition. This session's three occurrences don't fit that trigger: all three leaked commands have fully balanced quoting (paired double/single quotes, no unterminated strings or heredocs), and the third is a trivial single-line command with one quote pair and nothing else — not something that could hang a shell. There was also no user interruption, ESC, or resent message near any of the three points. Filing separately since this is a direct counter-example to the trigger #70148's triage has been narrowing toward, and I didn't want it to get lost in that thread — happy to have it merged there if a maintainer prefers.

The one pattern that does hold across all three here: each leaked call came immediately after a paragraph of descriptive/analytical prose (reasoning about a screenshot or a diff) rather than right after a short acknowledgment — a "prose, then tool call" turn shape, consistent with what other issues (e.g. #60584, #66153) note as a correlation for the plain leak on its own. What this report adds is that the same shape can also trigger the fabricated-turns escalation on top of the leak, without any hang/interrupt/latency involved.

What Should Happen?

  • Tool-call markup must never be emitted as plain text in place of a real tool_use block.
  • If that failure occurs anyway, the model must not continue by inventing subsequent user or system turns, and must not condition its next action on invented content. On detecting its own malformed output, it should stop and surface the failure rather than autoregressively simulating the rest of the conversation and acting on the simulation.
  • The fix can't rely solely on preventing shell hangs — this cluster shows the fabrication mechanism firing with well-formed, quickly-completing commands and no interruption.

Error Messages/Logs

[Assistant text block, single turn — schematic reconstruction of the pattern, repeated
3x in one session with different literal commands each time]

<normal prose analyzing a prior tool result>

call
<invoke name="Bash">
<parameter name="command"><a real, well-formed shell command — verified balanced quoting></parameter>
<parameter name="description">...</parameter>
</invoke>

user<short "retry"-type message that never actually appears as a real transcript entry>

<a fabricated system-level note, in the model's own voice, explaining that the tool call
is being "blocked" and stating a plan to change approach — also absent from the real
transcript>

[The next real transcript entry is either: (a) a genuine tool_use block retrying the same
work with a simplified/split command, confirming the model acted on the fabrication, or
(b) end_turn with the model reporting the task as complete without having actually retried,
justifying the non-retry by citing the fabricated block.]

Note on verification method: confirmed by loading the session's JSONL transcript and checking, for each suspected instance, whether the assistant entry's content array contains a tool_use block matching the leaked <invoke name=...> text. In two of three instances it does not (the leak is pure text, no corresponding real tool call was ever issued for that attempt). In all three, no user- or system-typed transcript entry exists between the leaked text and what follows it — everything is inside one assistant entry's single text content block.

Steps to Reproduce

Intermittent, as in related reports. Conditions common to all three occurrences here:

  1. An extended session doing iterative visual-verification work: repeated Bash calls (headless browser screenshot), Read of the resulting image, prose analyzing what was seen, then another Bash call — several cycles in.
  2. Each leaking call came immediately after a paragraph of descriptive prose, not right after a short acknowledgment.
  3. All three leaks were on Bash specifically (not observed on other tools in this session).
  4. No user message, ESC, or any interruption occurred between real turns at any of the three points — confirmed by transcript inspection, not just recollection.

To check a transcript for this specific escalation (beyond the plain leak): find an assistant turn whose text contains <invoke name= with no matching tool_use block, then check whether the text following the leaked markup contains anything resembling additional turns attributed to user/system that don't correspond to real adjacent entries.

Claude Model

Opus (claude-opus-4-8)

Is this a regression?

_No response_

Last Working Version

_No response_

Claude Code Version

2.1.196

Platform

macOS, native terminal (not IDE extension, not Desktop app)

Operating System

macOS 26.5.1 (Darwin 25.5.0), arm64

Terminal/Shell

zsh

Additional Information

Cross-referencing #70543 (linked from #70148) on compaction potentially preserving fabricated turns as authoritative history — not verified in this session since no compaction occurred in the relevant window, but the same risk would apply if compaction ran shortly after one of these three points.

View original on GitHub ↗