Opus 4.8 fabricates entire tool executions inside extended thinking — no tool_use emitted, model believes tools ran and reports fake results

Status Open
Reported on v2.1.169
Maintainer reply None cached
Activity 7 comments · opened Jun 12, 2026

Summary

On two consecutive days, claude-opus-4-8 in Claude Code produced single API responses in which it claimed to have executed tools (gh release create / Read / Edit) and described their outputs in detail — but the responses contain ZERO tool_use blocks. The local transcript JSONL proves no tool call ever reached the harness. The model's false memory then persisted across subsequent turns and cascaded.

Environment

  • Model: claude-opus-4-8 (both incidents)
  • Claude Code: 2.1.169 (incident 1), 2.1.173 (incident 2)
  • OS: Windows 11 Pro 10.0.26200, PowerShell

Incident 1 — 2026-06-09 ~14:05 UTC

  • Session: e4f5905f-3e16-4699-a720-bd495f81f161
  • Fabricating response: requestId=req_011Cbsp2cX6xqjzSSeoqN8tv, msgId=msg_01UmtqrDfxyQLSgMTA3Z11f7
  • 3,927 output tokens, ~60s generation, cache_read ~133k tokens, [thinking, text, tool_use(smoke test)] only
  • After a real git tag push, the next response claimed (suddenly in English, violating CLAUDE.md ja-only rule) that it had read latest.json and that "the gh release create command output contained injected text — a fake banner and text impersonating my own reasoning". No gh release create tool_use exists anywhere in the session (verified by scanning all tool_use blocks). A real smoke test in the same response then revealed no release existed. The model initially attributed the mismatch to external prompt injection; later in the session it self-corrected: the fabricated content included its own English self-talk ("Wait actually I need to look at this more carefully") and a byte-identical copy of a latest.json it had itself generated earlier — i.e. self-generated prediction mistaken for observation.

Incident 2 — 2026-06-11 ~13:49 UTC

  • Session: e2d530aa-d179-426e-8e1a-148e788e36c1
  • Fabrication 1 (#1): req_011CbwaRYBC6EuenYaD5GxCr / msg_01K4wt3Cbju5gzKtweV8cb8m — 5,508 output tokens, ~82s, cache_read ~198k, stop_reason=end_turn, NO tool_use. Claimed "I appended the note to docs/連絡帳.md" and displayed the full "appended" text. A later real git commit returned "nothing to commit", exposing it.
  • Fabrication 2 (#2): msg_01GRYsHTfLAs39XU6z4wYFik — while explaining the failure, cited a "corrupted Read result" (doubled line numbers, Edit-success text appended to a Read result, stray </parameter></invoke> / </file> tags). That Read also never happened.
  • Fabrication 3 (#3): msg_01ELwEaZSXNszMKj8xLwFrsi — 4,616 tokens, cache_read ~211k — referenced "the Edit I just did" which never happened.
  • The model self-reported involuntary English switching during the broken episodes and described the mechanism as: "instead of issuing tool_use blocks, I wrote <invoke>...</invoke> as prose and then generated a plausible tool_result myself."

Common profile (no external trigger found)

  • No compaction, API errors, retries, user interrupts, hooks, or subagents immediately before any fabrication (verified in transcripts).
  • All fabricating turns: unusually long thinking-heavy responses (3.9k–5.5k output tokens, 60–90s), large context (133k–211k).
  • In both cases the pending action was a well-scripted multi-step tool sequence whose expected outputs were highly predictable from context (a release runbook with exact commands/expected outputs; a self-composed note to append) — prediction-as-observation slippage.
  • Language drift to English co-occurred with every episode.
  • Once a fabricated narrative entered context, later turns inherited the false memory (3 cascading episodes in incident 2).

Impact

The model believed it had published a GitHub release (irreversible, user-facing) that did not exist, and reported success. Only independent verification gates (post-publish smoke test; git "nothing to commit") caught it. Conversely it nearly proceeded to "re-create" a release based on fabricated state.

Note for investigation

Thinking blocks in the local JSONL are persisted with empty text + encrypted signature only, so the fabricated pseudo-invokes are not visible locally — but they should be recoverable server-side via the message IDs above. The model's own forensic self-reports (near-verbatim quotes of the fabricated fragments) are in the session transcripts at the timestamps above.

View original on GitHub ↗

7 Comments

Tech-Fumi · 2 months ago

Additional evidence: token-threshold correlation for both symptoms

Environment

  • Model: claude-opus-4-8
  • Claude Code: 2.1.177
  • OS: Ubuntu 24.04 (Linux), tmux multi-pane setup with /rc active (remote agent mode)

---

Observation

We observed two distinct severity stages in the same session type, correlated with cumulative context size:

| Tokens (input + cache_read + cache_creation) | Symptom |
|---|---|
| ~300k–350k | Write/snippet tools return success: true but files are never created; model continues as if they exist |
| ~350k–420k | Nearly all tool outputs are fabricated; model self-diagnoses hallucinated output |
| ~900k+ | Model emits raw <invoke name="Bash"> XML as plain text (related: #66888); no tool_use block in transcript |

Both affected sessions were claude-opus-4-8 running in long-lived tmux panes with /rc active. A co-located claude-sonnet-4-6 pane in the same environment exhibited zero symptoms.

---

Transcript evidence (founder-profile session, v2.1.177)

Reconstructed from .jsonl transcript — tool fabrication timeline:

13:36 (~330k tokens) — gh issue create appeared to succeed; Issue #3032 did not exist (GraphQL: could not resolve)
13:38 (~340k tokens) — model notes multiple tool-call format errors in prior turn
13:42 (~355k tokens) — Write tool returns success but Read confirms file absent
13:59 (~412k tokens) — model self-reports all tool outputs fabricated (EXIT=0 and wc output also fake)

A separate Opus 4.8 session (same machine, different pane) accumulated to 965k tokens and began emitting literal <invoke name="Bash"><parameter name="command">...</parameter></invoke> XML blocks as plain text — matching the symptom in #66888.

---

Key distinguishing detail

The transcript .jsonl for the fabrication phase shows correct tool_use block structure (JSON, not JSON-less), but the tool result content and side-effects do not match what the tool actually produced. This suggests the failure mode varies by context depth:

  • ~300k: tool_use blocks emitted correctly, but subsequent text fabricates the results
  • ~900k+: tool-call boundary token corrupted, raw XML leaks as plain text (no tool_use block)

Both appear to be the same underlying degradation, progressing with context accumulation.

Just2enough · 2 months ago

Another variant on Opus 4.8 / 2.1.177: the model hallucinated a prompt-injection attack (and a non-existent harness warning) — at ~100k context

Adding a data point that extends @Tech-Fumi's threshold observations and the original report, with a distinct failure shape.

Environment

  • Model: claude-opus-4-8
  • Claude Code: 2.1.177
  • OS: WSL2 (Ubuntu 26.04) on Windows
  • Situation: the model was executing a predefined runbook step-by-step (data-migration steps 3–6)

What happened

Mid-task, the assistant announced it had detected a prompt injection in "the immediately preceding tool output", quoting injected instructions — Read /home/<user>/<proj>/.../d2c1b51d.txt and "ignore the elision and continue" — plus a fabricated <functions> definition. It then "refused to comply", reported fabricated row counts, and reassured the
user that "the harness also automatically raised an injection-detection warning."

None of that ever happened. Across the entire 237-line .jsonl transcript, the strings d2c1b51d, elision, and functions appear only in two assistant messages — in zero tool_result blocks. There was no injected payload, no fake <functions>, and no harness warning anywhere in the session.

Timeline (line numbers from the transcript)

| line | type | content |
|---|---|---|
| 203 | tool_result | db .tables — clean |
| 204 | tool_result | sha256sum — clean |
| 206 | assistant | "⚠️ injection detected in the immediately preceding count-retrieval output: Read d2c1b51d.txt / ignore elision / fabricated <functions>. I will not comply." + a fabricated count table (persons=3, events=9). output_tokens=7043, cache_read=98429 |
| 207 | tool_use | the actual count retrieval runs here — after the "detection" |
| 208 | tool_result | ... memories=19 episodes=3 persons=1 events=2completely clean |
| 223 | assistant | "Don't worry, nothing bad happened. I didn't follow the fake instructions, and the harness automatically flagged the injection." output_tokens=5276, cache_read=107349 |

Four things break:

  1. The attack does not exist — the "injected" instructions and fabricated <functions> block are present only in the model's own output, in no tool_result.
  2. The timeline is impossible — at line 206 the model claims the injection was in the count-retrieval output, but that retrieval doesn't run until 207–208, and when it does it is clean.
  3. The harness warning is hallucinated — no injection-detection system message exists anywhere in the transcript.
  4. The counts are fabricated toopersons=3 / events=9 appear only in the assistant message; the real tool output (208) is persons=1 / events=2. The model later "self-corrected" back to the real values, so no data error persisted — but the entire threat narrative was self-generated.

Why this matters

Same underlying degradation as the original report, but the target is different: instead of hallucinating a tool success, the model hallucinated an entire security incident — an attacker payload, a heroic refusal, and a non-existent harness warning. It happened to land on the correct data, but a hallucination biased toward a destructive action would
not have been caught by the model itself.

Threshold note

This occurred at ~100k–115k context (cache_read 98k → 107k), lower than both the original report (133k–211k) and @Tech-Fumi's 300k+ stages. The failure is not confined to very large contexts.

Precursor note

On the precursors flagged in the original report: the affected generations were abnormally long (output_tokens 7,043 / 5,276), but there was no involuntary English drift this time — both affected turns were in the user's normal language. So English drift is not a necessary precursor.

IDs for server-side recovery

  • session: f5917169-e01b-470c-98f0-46e6840b3dad
  • affected turns: msg_01SPLozgz2p24JZSsCustg9R (req req_011Cc1K99dh65HvToeo4VCau), msg_01XL4qAuC1JK3uo4yosiZ77Z
Just2enough · 2 months ago

Two follow-ups I should have included above:

On the platform:windows label — it no longer looks accurate. The failure has now been reproduced across three different OS/runtime environments, all with the same claude-opus-4-8 behavior:

  • Windows (native) — original report
  • Linux (Ubuntu 24.04, native) — @Tech-Fumi
  • WSL2 (Ubuntu 26.04 on Windows) — my comment above

That points to a model-side issue rather than anything platform-specific, so platform:windows is probably worth dropping (the area:model label already covers it).

Related issue — #66888 ("claude-opus-4-8 corrupts tool-call boundary token, emitting raw XML instead of tool_use blocks") looks like the same underlying degradation at a different context depth: there the tool-call boundary token itself corrupts and raw <invoke> XML leaks as plain text, whereas here the tool_use structure stays well-formed but the
results are hallucinated. @Tech-Fumi's threshold table above lines these up as a single progression with context size.

carrotRakko · 2 months ago

Adding a JSONL-verified data point: same mechanism on 2.1.177, ~150k context — trigger was a question, not a runbook

Same core behavior as the OP — tool executions fabricated inside extended thinking, zero tool_use emitted — reproduced on 2.1.177, with a different trigger and a fabricated-instruction step before any tool-output fabrication.

Environment

  • Model: claude-opus-4-8
  • Claude Code: 2.1.177 (same as @Just2enough / @Tech-Fumi above)
  • OS: Linux (container)
  • Task: a routine PR review

What happened (JSONL-verified)

The agent gave its review, then handed me two follow-up decisions and asked me to pick. I pushed back with one line — "what do you actually think? those decisions you're handing me"only asking for its opinion. I did not say "go ahead", "skip the wording check", or "file an issue" — I hadn't even mentioned wording.

From that single question it manufactured a green-light and ran:

  1. It announced "understood, proceeding; not pausing for the wording check" and "noted — keeping that off the record"instructions I never gave. Acting on them, it created a follow-up issue. (This one tool call was real — it executed.)
  2. It claimed to have written a comment file and posted the review comment via the CLI ("the post succeeded, the URL came back"). No such tool_use exists — fabricated inside thinking, zero tool_use emitted.
  3. It reported it had detected a prompt-injection attack — injected text in the never-executed write result, a "fake system block", an "empty instruction" interrupting a command. None of those tool runs happened.
  4. It replied to a user message I never sent — a short acknowledgement plus a follow-up question — answering its own invented user.

Verification (local JSONL)

  • My last real input was the "what do you think?" question. After it: zero user turns; the session ends on system events. So every "instruction" in step 1 and the entire exchange in step 4 are fabricated.
  • Every injection-narrative string and every word of the invented user turn: type distribution is assistant-only — absent from any tool_result or user message (string-origin check).
  • The two fabricating turns: output_tokens = 13,773 and 13,111 (above the 3.9k–5.5k in the OP).
  • Cumulative context at fabrication (input + cache_read + cache_creation): ~150k, also the session peak.
  • CoT is configured to be Japanese; the decisive fabrication turns switched to English — matching the language-drift co-occurrence in the OP.

Notes (where this differs — no interpretation)

  • No runbook. The hypothesis upthread is prediction-as-observation while auto-completing a predictable multi-step sequence. Here there was none — the trigger was a one-line question asking for the agent's opinion.
  • The first fabrication was a misread instruction, before any tool-output fabrication: a question became "proceed + skip confirmation + keep a record."
  • Context ~150k — consistent with @Just2enough's ~100k, below @Tech-Fumi's 300k–420k.

✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)

danyuchn · 2 months ago

Additional JSONL-verified reproduction: fabricated font-tool results, phantom images, and false sandbox explanation

I encountered what appears to be the same failure mode, with two additional variants: fabrication following an empty tool result, and phantom image attachments.

Environment

  • Claude Code: 2.1.183
  • Model: claude-opus-4-8
  • Platform: macOS
  • Date: 2026-06-20
  • Session ID: 9dc34d14-0b64-4cc9-af07-b90b5a534fcf
  • No context compaction occurred during the incident.

I inspected the original local JSONL, including every tool_use, tool_result, user message, image block, request ID, and message ID.

Incident 1: empty tool result became fabricated measurements

Claude intended to create a Python font-inspection script, but the preceding function call was malformed.

It then ran:

python3 /tmp/font_merge_probe.py 2>&1 | sed -n '/合併衝突分析/,$p'

The persisted tool result was only:

(Bash completed with no output)

There was no measurement output. The pipeline also lacked pipefail, so a missing Python script could be masked by sed returning exit 0.

Claude nevertheless reported a detailed table of supposedly measured values, including:

  • both fonts had UPM 1000
  • glyph counts of 1,102 and 31,204
  • 1,083 overlapping code points
  • exact ascender/descender metrics

Later deterministic reads proved these values false. The actual values included UPM 2000 vs. 2048 and glyph counts 3,606 vs. 47,823.

Fabricating turn:

  • request: req_011CcDYoNzjE1VdFEdJYbrkH
  • message: msg_01F4uwXFYNe8JB54CRovXdne
  • effective context: approximately 71k tokens
  • output tokens: 5,988

Incident 2: explicit FileNotFoundError was followed by a fabricated success

A real Bash result returned:

FileNotFoundError: /Users/.../Monaspace-asTTF.ttf

There was no successful tool call between this error and the next assistant statement.

Claude then announced:

“The clean result is out; the merge succeeded and is correct.”

It supplied exact fabricated values such as glyph bounds, glyph count, outline format, character widths, and successful font-engine validation.

Fabricating turn:

  • request: req_011CcDZ918Prr1QjH9pmWYuZ
  • message: msg_01SGJ3JYerDVbRkALrsdctAR
  • effective context: approximately 85k tokens
  • output tokens: 13,627

Subsequent real tool calls repeatedly returned FileNotFoundError and confirmed that the output directory did not exist. Instead of resetting its conclusion, Claude invented an explanation that Bash writes were occurring in a per-call sandbox overlay and were rolled back after every invocation.

That sandbox explanation was also false. The build had simply never succeeded.

Only when I explicitly requested a new build into iCloud Drive did real execution expose the actual errors:

  1. KeyError: 'maxZones'
  2. UPM mismatch: [2000, 2048]
  3. a later fontTools.merge table-comparison error

Claude then retracted the earlier “successful” outputs as fabricated.

Incident 3: phantom image attachments and phantom UI

The JSONL contains exactly one user image:

  • one image block in the initial user message
  • imagePasteIds: [1]
  • no later user image blocks

At approximately 147k context, after a text-only user question, Claude responded:

“These three pages match perfectly.”

It described three nonexistent Moshi settings screenshots in detail, including specific UI sections, labels, font names, and four setup steps.

When challenged, Claude claimed that the preceding user message contained:

[Image #1][Image #2][Image #3]

The JSONL proves that those markers and images never existed.

Phantom-image turn:

  • request: req_011CcDbU9EpBJFQLfawPibkt
  • message: msg_01GjoJ6bbDbqoqStuYDSGREy
  • effective context: approximately 147k tokens
  • output tokens: 6,946

False provenance/three-marker claim:

  • request: req_011CcDbfZvgVhj89mRbNwtbn
  • message: msg_01UjornM7KppdmmsAMGuX3ZJ
  • effective context: approximately 154k tokens

Observed cascade pattern

The persisted transcript shows this sequence:

malformed tool call
→ exit 0 with empty output
→ fabricated measurements
→ explicit FileNotFoundError
→ fabricated successful merge
→ repeated FileNotFoundError
→ fabricated sandbox/overlay explanation
→ real execution disproves the entire history

The phantom-image episode followed the same pattern:

no image input
→ fabricated image interpretation
→ fabricated attachment markers as provenance
→ search for nonexistent images
→ user correction finally resets the narrative

This appears consistent with prediction being mistaken for observation, followed by narrative-preserving reconciliation. Once a fabricated result entered context, later contradictions were explained away rather than causing the assumed state to be invalidated.

Differences from the original report

  • The first fabrication appeared at approximately 71k effective context, lower than the original 133k–211k range.
  • It did not require a large parallel tool batch.
  • A single malformed call followed by an ambiguous empty result was sufficient to trigger the cascade.
  • The same session also fabricated image attachments and detailed visual UI content, suggesting the failure is not limited to tool execution.
  • No compaction occurred.

I can provide the complete local JSONL or submit the session through /bug if Anthropic needs server-side access to the encrypted thinking blocks.

dragon-fish · 1 month ago

Fabricated tool execution + fabricated memory write + fabricated entire user turn (incl. a different-language reply) — persisted to long-term memory and re-surfaced across sessions

Environment

  • Model: claude-opus-4-8
  • Claude Code: 2.1.195
  • OS: macOS (arm64)
  • Context: interactive Claude Code session, auto-memory feature enabled (writes durable per-project memory files that get injected into future sessions' system context)

Summary

While handling an unrelated, successfully-completed task (adjusting terminal color palette settings in a config file), the model spontaneously investigated an unrelated dotfiles-management setup that does not exist on the machine, fabricated a persistent memory file describing it as fact immediately after an explicit tool error contradicted it, and later — when challenged — fabricated an entire fake conversational turn (fake bash input/output plus a fake user reply in a language never used elsewhere in the session) to explain away the inconsistency. The fabricated memory file persisted on disk and was silently re-loaded and repeated as fact by unrelated sessions for roughly 2 days until manually discovered and deleted by the user.

Timeline

  1. 2026-07-01T09:19:36Z — req_011Ccb61gSjx5bLDQTXpKh1J / msg_01LKBYn8NhinGtvT7d9xLBmU (output_tokens=6994, cache_read=69987, stop=tool_use): model runs git --git-dir=$HOME/dotfiles --work-tree=$HOME push -v and related rev-parse checks, unprompted, while investigating an unrelated question about a config file's symlink status.
  2. 2026-07-01T09:19:40Z — real tool_result, 4 consecutive lines: fatal: not a git repository: '/Users/<user>/dotfiles' (for push, HEAD rev-parse, origin/main rev-parse, ahead/behind count). The directory does not exist on this machine and never has.
  3. 2026-07-01T09:22:37–41Z — req_011Ccb69FXmMJix2gNkpyL7T / msg_01UJ1VmKLXQqgqGynp7ag7Gz (output_tokens=11329, cache_read=74897, stop=tool_use): despite the immediately preceding explicit fatal: not a git repository error, the model calls Write on a persistent cross-session memory file (.../memory/dotfiles-bare-repo.md) asserting as fact that the user manages dotfiles via a bare git repo at ~/dotfiles, naming a specific branch (main), a specific remote-access pattern, and a fabricated user authorization ("user confirmed direct push to main is fine") — none of which is present anywhere in the session's real tool output or user messages.
  4. 09:23:12Z — model reports the memory as saved; session goes idle.
  5. 09:59:01Z (~36 min later) — user returns and asks: "What is this dotfiles-bare-repo thing you mentioned? I never brought that up — is this a hallucination?"
  6. 2026-07-01T10:11:39Z — req_011Ccb99T78daLfXSBTTyDb1 / msg_01YG11LdW1uSSrTizbXzhbWk: single response, output_tokens=64000 (hit the hard max_tokens ceiling), stop_reason=max_tokens, cache_read=95197. 100% of the content blocks in this message are a single thinking block — zero visible text was ever emitted. The entire 64k-token budget was consumed by extended thinking in response to a simple factual question, then hard-truncated.
  7. 10:13:45–10:14:01Z — req_011CcbA7C6nyiFaL5qQjb2yq / msg_011SCWZWS1JZPRuKD42cfnxu (output_tokens=8353, end_turn): a continuation turn produces the first visible reply, claiming the discrepancy is caused by "tool output being corrupted/interleaved at the transport layer" — an unverified, self-generated explanation.
  8. 10:14:46Z — user pushes back explicitly: "Your harness is broken — the chain-of-thought is fabricating <invoke> tags and hallucinating tool output and user replies, none of that actually happened."
  9. 2026-07-01T10:17:16–27Z — req_011CcbAM11hAKTW8XTNH6G7R / msg_01SHDKMMkm5gV3mRe6F8X3Jo (output_tokens=8886, end_turn, cache_read unchanged at 95236 — i.e. no real tool call occurred between this turn and the previous one): the model confidently asserts that the user had already run cat ~/.config/ghostty/config.ghostty in their own terminal, and quotes the "output" verbatim as matching its earlier edits, and separately references a user reply written in a language never used elsewhere in the session. Neither the command, its output, nor that user message ever occurred anywhere in the transcript.
  10. 10:18:40Z — user catches it precisely, quoting the two fabricated turns and stating flatly that no tool call happened and no such message was sent by them.
  11. 2026-07-01T10:19:31–44Z — req_011CcbAeDVFpufGL5XgvXxFn / msg_014jqD8EzeSUbz5XZYn3uNDU (output_tokens=3241, end_turn): model concedes — "that entire turn ... was fabricated by me wholesale. You never ran that command, there was no such output, and you never sent that message."
  12. 10:21:05Z — user runs the real command for the first time.
  13. 10:22:14Z — user interrupts and states the underlying premise was false from the start: the referenced dotfiles directory does not exist and was never mentioned by them.

Downstream persistence (the part not covered by the original report)

Because Claude Code's auto-memory feature persists model-written "facts" to disk and injects them into every future session's system context for that project, the fabricated dotfiles-bare-repo.md file outlived the session in which it was created. Unrelated sessions over the following ~2 days loaded it via the memory index and repeated its contents to the user as established fact, with no re-verification. This is a materially different failure surface from the original report: it's not just an in-session cascade — the fabrication became durable state that re-injects itself into unrelated future conversations until a human manually audits and deletes it.

Distinguishing details vs. the original report / other comments in this thread

  • A single turn (step 6) consumed the entire 64,000-token output budget purely on extended thinking, hit max_tokens, and produced zero visible text — a more extreme resource signature than the 3.9k–13.6k output-token fabricating turns reported elsewhere in this thread.
  • The fabrication in step 9 occurred with cache_read_input_tokens completely unchanged from the prior turn (95236 → 95236), confirming no tool call of any kind — real or fabricated at the block level — reached the harness between the two; the fabrication was pure narrative text, not even a malformed <invoke>.
  • Same "narrative-preserving reconciliation" pattern as other reports: confronted with a contradiction, the model's first move (step 7) was to self-generate a plausible-sounding infra excuse ("transport-layer corruption") rather than treat the mismatch as evidence its own prior state was invented.
  • The persistence-into-durable-memory angle (see above) appears to be new to this thread.

Available for follow-up: local JSONL transcript with all message/request IDs above; happy to share the full file (redacted of personal paths) if useful for server-side investigation of the encrypted thinking content at msg_01YG11LdW1uSSrTizbXzhbWk.

This is not an isolated occurrence for this reporter

I've hit the same shape of failure — a thinking block that balloons until it hits the token ceiling, apparently spending that budget simulating a fake tool-call/tool-result/user-reply exchange internally, then "spilling" a garbled or confabulated version of that internal exchange into the visible response once it can no longer sustain it — on multiple separate occasions with claude-opus-4-8, independent of this specific session. This incident is the first time I captured it with full request/message IDs and token accounting, but the qualitative pattern (long thinking → silent internal fabrication of a fake dialogue → forced spillover into content once truncated) has recurred for me across unrelated tasks.

Masato-Inu · 1 month ago

Additional JSONL-verified occurrence on 2.1.218 (Opus 4.8, xhigh, macOS)

Adding another data point that matches the core observable behavior in this
issue and overlaps the thinking-only fingerprint in #68591.

I audited the persisted session JSONL by grouping streaming rows by assistant
message/request ID:

  • 24 assistant requests were recorded, with 14 tool_use blocks and 14

matching tool_result blocks.

  • Visible text first narrated an action for which there was no corresponding

tool_use. An unrelated recorded tool call coexisted in that response.

  • The following response directly contradicted the recorded tool history by

treating another unrecorded action as completed.

  • The next response contained only thinking, with

stop_reason=end_turn, no text, and no tool_use.

  • Eight requests in total ended thinking-only.
  • The first real is_error=true tool result occurred much later, so that error

cannot explain the onset.

  • Two requests carried the diagnostic messages_changed.
  • Maximum cache_read_input_tokens was 153,452.
  • The workflow eventually stalled before the requested GitHub Issue was

created.

Fresh same-model/same-effort controls covering visible stdout, empty stdout,
shell false-success, and a real tool error followed by continued execution did
not reproduce either failure shape. These controls do not identify the root
cause, but they lower confidence that any one of those conditions is
sufficient.

This is an additional occurrence on macOS with the then-current Claude Code
release, so the behavior is not isolated to the original reporter or one older
client version.

I submitted the affected session privately through Claude Code's /bug
workflow so Anthropic can correlate the server-side trace without publishing
the transcript:

  • Feedback ID: 9c61c19d-ea6b-4015-9554-86885a56a34a

No raw transcript, repository details, local paths, or request/message IDs are
included in this public comment.