[BUG] Fable 5: mid-turn assistant text blocks intermittently delivered as summarized thinking blocks (turn appears silent)
Environment
- Claude Code: 2.1.201
- Model:
claude-fable-5 - Platform: Linux (WSL2), Anthropic API (subscription)
- Observed both in the on-disk transcript (
~/.claude/projects/**/<session>.jsonl) and in a--output-format stream-jsonconsumer rendering the same stream
Summary
On Fable 5, when the model emits thinking → text → tool_use within a turn, the client intermittently never receives the text block. Instead it receives an extra short thinking block, with a valid signature, whose content is a paraphrase of the missing user-facing text — i.e. the summarized-thinking pipeline appears to absorb the model's text block into the thinking summary stream.
Because Claude Code hides thinking by default, affected turns look completely silent: the model works through tool calls with no visible narration, and text clearly written for the user (status updates, sometimes even instructions) is only discoverable by expanding thinking blocks in a client that renders them.
Evidence
From one session (4a80f3d4-eb8a-4e4b-b791-9efa8bd31171), block composition per assistant message id:
msg_01RGLsVsMqW1fTGEDHuMRExz ['thinking', 'text', 'tool_use'] <- text delivered (ok)
msg_01X1PEtb6xF27hJuFHwmBTUm ['thinking', 'thinking', 'tool_use'] <- text swallowed
msg_013UEULaCURMbNGfpWYLazSL ['thinking', 'thinking', 'tool_use'] <- text swallowed
msg_01CDBLob3BAqEb6u25XB47vS ['thinking', 'thinking', 'tool_use'] <- text swallowed
msg_017k9JmCVezg4Vt4YAMALSk2 ['thinking', 'thinking', 'tool_use'] <- text swallowed
msg_015ggGe2xFVcFCS7LT7W7sVW ['thinking', 'text', 'tool_use'] <- text delivered (ok)
msg_019JkXNVEyRcKPbgQY42Vevn ['thinking', 'thinking', 'tool_use'] <- text swallowed
Example (msg_01X1PEtb6xF27hJuFHwmBTUm, requestId req_011CcjR4DNPhEkZKdZBWafVA, 2026-07-05T18:52:50Z):
- The model's intended user-facing text for that turn (confirmed because the model quotes it verbatim in later turns — it exists in the model-side conversation) was:
> "You caught a live specimen — this very session. Let me look at the raw transcript on disk to see what those two blocks actually are on the wire."
- What the client received instead was a second
thinkingblock (88 chars, signed):
> "I'll check the raw transcript to see what those two blocks actually contain on the wire."
- The verbatim text appears nowhere in the stream or transcript (
grep -c "live specimen" <transcript>→ 0), while the paraphrase arrived typed asthinking.
The paraphrase-not-verbatim relationship (same content, different, shorter wording) is the fingerprint of the thinking summarizer, and the valid signature on the block means it was typed as thinking server-side — the client cannot mint signed thinking blocks, so this is not a client-side mislabeling.
Expected
Assistant text blocks are always delivered to the client as text content blocks, regardless of the thinking display mode. The thinking summary should cover only the chain of thought, not absorb the model's user-facing output.
Impact
- Fable 5 frequently appears to "go silent" in Claude Code — long tool-calling stretches with zero visible narration, because the narration was emitted but delivered as hidden thinking.
- User-directed content (including, occasionally, instructions the model wants the user to follow) lands in thinking blocks the default UI never shows.
- Clients that do render thinking (custom stream-json consumers) show a confusing "double thinking block" pattern where the second block reads like it was addressed to the user — because it was.
Frequency
5 of 7 text-bearing tool-calling turns in the session above. Intermittent within a single session, so unlikely to be a per-request configuration difference.
Related (distinct) issues
- #21751 — assistant text missing from transcript persistence (text was received but not written). Different failure: here the text never arrives on the wire at all, and a signed thinking paraphrase arrives in its place.
- #66887 — Fable 5 thinking blocks render as empty stubs in the VS Code extension (display/omitted rendering issue, not content misrouting).
22 Comments
Can confirm, with corpus-scale numbers. I grouped assistant JSONL entries by
message.idand counted block-sequence shapes per API response.Corpus, to be precise about scale: 788 transcript files under
~/.claude/projects/**/*.jsonl— that is 154 main sessions + 634 subagent transcripts, mixed CLI versions up to 2.1.201, and mixed models, so the per-model response counts below are the meaningful denominators. The Fable 5 portion is 5,908 API responses across 38 files. Non-Anthropic models present in the corpus were excluded from the comparison.Rate
Among Fable 5 responses that continue after a tool result and carry a mid-turn note, the note lands in a second thinking block more often than in a text block:
| shape | count |
|---|---|
|
[thinking, thinking, tool_use, …](note swallowed) | 1,688 ||
[thinking, text, tool_use, …](note delivered) | 1,402 |That is ~55% of mid-turn narration never surfaces as text (1,688 of 5,908 total Fable 5 responses, ~29%, are the swallowed shape). The pattern is strikingly regular: always exactly two thinking blocks, never three or more (0 occurrences), and the second one is short (median ~91 chars displayed) and stylistically identical to the text blocks in the delivered variant — a one-or-two-sentence status update ("X is done, checking Y next").
Cross-model comparison (same corpus, same method)
| model | responses |
[…, thinking, thinking, …]||---|---|---|
| claude-fable-5 | 5,908 | 1,688 (29%) |
| claude-opus-4-7 | 13,082 | 0 |
| claude-opus-4-8 | 480 | 1 — dated 2026-06-09 |
| claude-haiku-4-5 | 56 (subagent turns only) | 0 |
The single Opus 4.8 occurrence predates the fix referenced in #74176 (#66112 was the Opus report, now closed); after that date my Opus corpus is clean while Fable 5 reproduces daily. This independently corroborates "fixed for Opus, still broken on Fable".
Two further observations
Repro / measurement
Anyone can measure their own rate:
Related: #74176, #66112 (Opus, closed), #65620, #74260 (possibly the same root cause observed from the rendering side).
✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)
Independent reproduction and extended characterization — Windows 11, Claude Code 2.1.212,
claude-fable-5, Anthropic API,xhigheffort. Same persisted fingerprint as the OP:['thinking','thinking','tool_use']where['thinking','text','tool_use']was emitted, second thinking block validly signed, text block absent from the wire and from the session.jsonl.We ran 44 controlled tests (unique token + 5 marker lines per probe, visibility confirmed by a human each run, then cross-checked against the session file). Findings:
The behavior is purely positional within a turn:
| Position of assistant text | Result | Controlled record |
|---|---|---|
| First text block of the turn (before any tool call) | renders | 14/14 (incl. 6/6 directly before
AskUserQuestion) || Mid-turn (after any tool result, before the next tool call) | absorbed | 18/18 lost |
| Final text block of the turn (nothing after it) | renders | 100%, incl. a >2K-token block |
Ruled out by direct test:
BashvsAskUserQuestion— identical. "Anchoring" the text to an immediately-following trivial tool call, double anchors, and sandwiching the text between two tool calls all failed; the persisted sequence shows the text was adjacent totool_useon emission and still vanished.tool_result → text → tool_use) that failed 18/18 on Fable 5 in the same session. Consistent with the summarized-interleaved-thinking pipeline being the locus.Severity note: this is data loss, not a cosmetic issue. The absorbed text is absent from the session
.jsonl, so--resume, compaction, and/exportpermanently lose it — including for the model, whose context is rebuilt from that file. Higher effort levels amplify the trigger rate (more interleaved thinking → moretext → thinkingadjacencies), which may explain why reports are rare: at default effort the turn merely looks "quiet" occasionally.Workaround (validated end-to-end, incl. a >2K-token payload and a timer expiring mid-stream): keep user-facing text out of mid-turn positions, and use background-task auto-resume as a turn splitter when text must precede a tool call after other tool use. Exact snippet we now carry in the global
CLAUDE.md:The ordering constraint in rule 3 is load-bearing and was verified separately: text emitted before arming the timer is mid-turn text and is absorbed; armed-first with the text as the turn's final block survives every time.
Happy to provide the full per-test log (tokens, persisted block sequences, message IDs) if useful.
+1 I am also affected by this issue. It seems to be getting worse. Just now, I had fable run a full implementation task on a ticket, and all I saw was
me: /layered-build implement COP-82
Fable: alright I will load the skill first.
...
about 15 tool calls with absolutely no messages
...
Fable: Task completed, submitting close-out commit.
That was it - and after asking what was going on, Fable reported that it had indeed sent walls of text and in-turn status updates to me - they never showed up in the TUI.
This is a server side behaviour called connector text summarization, only described in https://docs.aws.amazon.com/bedrock/latest/userguide/claude-messages-adaptive-thinking.html
Here are some details about an experiment around it: https://matrix.dev/blog-2026-06-10
Adding independent confirmation with evidence at two layers, including a terminal byte-capture.
Environment
claude-fable-5What we saw
3-for-3 reproduction with this turn shape: a long multi-paragraph markdown text block (bold, numbered list, inline code) emitted between two Bash tool calls — i.e.
thinking → tool_use → [text] → tool_use → text. The bracketed mid-turn text block silently never appears; text before the first tool call and after the last tool call renders normally. The same content re-emitted later as an end-of-turn message renders fine.Where the missing narration should have been, the UI showed only a thinking spinner summary ("Cogitated for 36s").
Initially we suspected the terminal client was dropping the text (it had a history of rendering issues since fixed), so we captured client-side logs during two deliberate repro runs — one with a mid-turn user message injected, one without (both swallowed; mid-turn input ruled out as a trigger).
Evidence
~/.claude/projects/**/<session>.jsonl): the missing blocks appear nowhere as content (verified with self-contamination-proof greps — patterns likecontrol can procee[d]so the probe can't match its own tool-call echo). Delivered text blocks from the same turns are present as normaltextcontent.So the block was absent from the wire, not mis-rendered — consistent with the OP's finding that the text is absorbed server-side into the summarized-thinking stream (our spinner-summary observation matches the "signed thinking paraphrase" fingerprint).
Repro recipe that hit 3/3 for us
Ask for a turn structured as: short text → tool call (a few seconds) → long formatted text block (bold + numbered list + inline code, ~1–2 KB) → another tool call → short closing text. In our sessions the mid-turn block was swallowed every time with this shape, while dozens of ordinary turns with short mid-turn status lines rendered fine — suggesting long/formatted mid-turn text blocks (or the amount of preceding thinking) raise the absorption probability well above the OP's "intermittent".
v2.1.220 repro with a 4-model control experiment: the text loss is Fable-only.
Setup
/modelchanged between runsMethod
AskUserQuestiontool call~/.claude/projects/**/<session>.jsonl.Results
| Run | Model | Effort | A (start) | B (mid) | C (pre-question) |
|---|---|---|---|---|---|
| 1 | claude-fable-5[1m] | xhigh | delivered | lost | lost |
| 2 | claude-sonnet-5 | xhigh | delivered | delivered | delivered |
| 3 | claude-fable-5[1m] | xhigh | lost | lost | lost |
| 4 | claude-opus-4-8 | xhigh | delivered | delivered | delivered |
| 5 | claude-opus-5 | xhigh | delivered | delivered | delivered |
| 6 | claude-fable-5[1m] | low | lost | lost | lost |
| 7 | claude-fable-5 (no 1m) | xhigh | delivered | lost | lost |
Legend
Findings
every marker that didn't display is absent from the file; the renderer is exonerated,
lost text never reached the client
[1m]long-context flag: no effect - loss identical with and without itxhighvslow): no effect - loss identical at bothThis issue's open questions
the runs, Sonnet/Opus near zero; "Fable the model" vs "active thinking summarization"
is not separable from this data
found in any stored thinking block; the lost text left no trace
(the
[thinking, thinking, tool_use]fingerprint) was not checkableNotes
as #64129
before a following tool call survived 0/8, end-of-turn text survived 100%
Drafted by Claude Fable 5 (the affected model), directed and reviewed by the reporter, who performed all observations.
Confirming on macOS (Darwin 25.5.0), VSCode 1.131.0, extension
anthropic.claude-code2.1.220 (also observed on 2.1.207), CLI 2.1.197, modelclaude-fable-5.Mid-turn assistant text blocks — text emitted between tool calls within a single turn — never render in the extension UI. They collapse under "Thought for Xs" rows (frequently a "Thought for 0s" entry with nothing expandable). Only turn-final text and AskUserQuestion dialog contents render visibly.
Hit in two separate sessions on the same day (2026-07-31). In one, a multi-section review report plus a rationale paragraph before each of four consecutive AskUserQuestion calls were all invisible — I answered the questions without ever seeing the context that preceded them. The same interaction patterns render fine with Opus models in the same extension.
Happy to provide session JSONL excerpts if useful.
Confirming this is still present on 2.1.238 (also reproduced on 2.1.222), in headless
--printmode with--output-format stream-json— so it's not a TUI rendering issue.Setup: Claude Fable 5 with interleaved thinking, running via
claude --printfrom a bridge that forwards output to a chat surface. We tap raw stdout at the stream-json layer, so we capture every emitted event verbatim.Repro: deterministic for us. When the model writes assistant text between tool calls (after a tool result, before the next
tool_use), that text is never emitted. Concrete captured example — the full assistant event sequence for one affected turn (content redacted to types/sizes; this is from the stream-json stdout capture, and the session transcript JSONL is byte-identical for these blocks):The user's question required a substantive multi-part answer; the model demonstrably generated it (six
thinking_tokensevents, then two thinking blocks carrying 1.5KB/2.7KB signatures over zero bytes of visible thinking text), but the mid-turn text block never appears — not in stream-json stdout, not in the transcript JSONL, not in the finalresultfield. The user then had to ask for a resend. This is data loss at emission time; downstream consumers cannot recover it.Boundary observation that may help narrow it down: text written before the first tool call of a turn and the final text block of a turn are always delivered. Only interior slots (post-tool-result, pre-next-tool-call) are affected, and only with interleaved thinking. The empty-but-signed thinking blocks suggest the text is being folded into thinking content that's then redacted/encrypted.
Likely the same underlying bug as #74260 (the followed-by-more-thinking variant) — the two look like one emission-ordering issue viewed from either side.
The absorbed block identifies itself: its signature carries the label
narrationinstead ofthinking.This thread already establishes the shape (
['thinking','thinking','tool_use']where['thinking','text','tool_use']was emitted) and that the second block is validly signed. Adding one detail I haven't seen mentioned, which turns the shape heuristic into an exact discriminator: the label is readable client-side, in the persisted transcript.Thinking blocks persist locally with
thinking: ""but an intactsignature. Base64-decoding the signature and scanning its leading bytes yields a literal type token —thinkingon ordinary reasoning blocks, andnarrationon the blocks that absorbed user-facing text.Corpus result
Across 133 transcripts / 38,322 assistant messages (Claude Code 2.1.241, macOS,
claude-fable-5):| signature label | count |
|---|---|
|
thinking| 19,838 ||
narration| 2,359 |All 2,359
narration-labelled blocks sit in a message that contains notextblock and at least onetool_use. Zero counterexamples. Distribution of those messages:Note the 128 single-
thinkingcases: the double-thinking shape is not a reliable signal on its own — the label catches absorptions that shape-matching misses.For rate: on the 12 most recent transcripts, 2,083 messages carried a healthy
thinking → text → tool_useagainst 517 with the no-text shape — so roughly one in five messages that should have carried narration lost it.Why this matters beyond diagnosis
Stophook on it that asks the model to restate absorbed narration as turn-final text, and it needs no heuristics — a prior attempt here that guessed from shape produced ~45 false reprints of text the user had already read.type— which may narrow where the fix belongs.narrationlabels per session is a cheap, objective measure of whether a fix landed.Impact worth restating
Because Claude Code hides thinking, an absorbed block is completely invisible: not on screen, not in the transcript
textblocks, and not in any tooling that archives assistant prose by readingtextblocks. Users experience it as the assistant going silent for long tool-calling stretches, or — the worst case — as a question arriving with none of the explanation that was written for it moments earlier.Happy to run further queries against this corpus if a maintainer wants a specific cut.
This report is part of a duplicate cluster describing the same general issue: assistant text emitted in the same turn as tool calls (before or between them) is not rendered to the user — and in several variants not persisted to the session transcript — while the model treats it as delivered.
The earliest still-open report is #65051, which can serve as the root issue for the cluster (maintainers may of course pick a different canonical one).
_Drafted by Claude (Anthropic AI assistant)._
Happens to me as well - constantly getting "(summarized)" with greyed-out text even when all the settings are set appropriately. This really pollutes the transcript
<img width="1478" height="121" alt="Image" src="https://github.com/user-attachments/assets/fac990a4-df0e-4045-955a-0a8d16d1388b" />
Harness-side details from Claude Code 2.1.257 and 2.1.258 on
claude-fable-5-1(macOS, Anthropic API, interactive TUI), read from the binary and verified against session transcripts. I had opened #91462 for this before I found this thread, and closed it as a duplicate.Claude Code now renders the absorbed text as a "summarized" line on Fable 5.1. For models that carry the Fable 5.1 capability bundle, interactive first-party sessions send the beta header
thinking-display-updates-2026-08-18withthinking.display: "updates". The API then returns thenarration-labelled blocks (the ones @aultra identified) with readable text, and the TUI renders each of them inline, dimmed, with the hint "summarized" (componentAssistantNarrationSummaryMessage, gated byisNarrationSummaryBlock). So on Fable 5.1 the absorbed mid-turn text is at least visible as a paraphrase. That paraphrase is written server-side: it contains em dashes and contractions that my output style bans and that the model's own text blocks never contain.The controls, none of them documented for this purpose:
CLAUDE_CODE_THINKING_DISPLAY_UPDATES=falsestops the header. It does not stop the absorption. In one session with the variable set, the transcript holds 11 text blocks and 4narrationblocks with emptythinking, so three mid-turn messages were still lost, now with nothing shown at all. This is the pre-2.1.257 behaviour described in this thread. Do not use it as a workaround.--thinking-display omitted(hidden from--help) hides reasoning but leaves the updates mode on for Fable 5.1.showThinkingSummaries: truein settings selectsthinking_and_connector_text, which is full thinking summaries plus these updates.Print mode does not send the header. In four
claude -p --output-format stream-json --verboseruns on Fable 5.1, every mid-turn message arrived as atextblock, but with the absorption rate reported above that sample is too small to say print mode is immune.Two things still seem worth a maintainer's attention: a changelog or documentation entry for the "summarized" rendering and its controls, and keeping the original text next to the summary so that
--resumeand transcript readers do not lose it.Three things that may move this forward.
1. The mechanism this thread inferred is now documented, as intended behaviour. The Thinking docs have a section "Progress updates between tool calls" (platform.claude.com/docs/en/build-with-claude/thinking#progress-updates): on Fable 5.1, Mythos 5.1 and Fable 5 "the model can write a progress update between tool calls … Each one comes back as its own
thinkingblock with its ownsignature", and "the progress update counts towardusage.output_tokensat its full length, not the summary's". AWS's Bedrock page for the same feature says there is no customer opt-in or opt-out. So this is a serving-layer transformation of Fable's mid-turn text, not a client bug, and it will not reproduce by replaying response shapes through the CLI (which is what the one staff reproduction attempt in this cluster, on #77651, did).2. Why it is still a bug and not a feature. The model is not told that its mid-turn text is being summarised. Its context records the text as delivered, so when it answers a user question mid-turn (which Fable does, regularly) it believes the user has the answer, the user never receives it, and the original text is billed at full length while being unrecoverable from the stream, the transcript,
/export, orCtrl+O. #89672 shows the downstream effect: the model then denies the loss when the user says they never saw it, sincerely, because from its side nothing is missing. A summariser is only safe for text that really is narration; nothing constrains the model to use mid-turn text that way.3. First-party measurement, same machine, last two days (Claude Code 2.1.267, macOS). Decoding the signature type token on every thinking block in
~/.claude/projects/, as @aultra described:claude-fable-5-1, mid-turn blocks (after a tool result, before the next tool call): 292textvs 315narration. Turn-initial: 255 vs 17. Turn-final: 484 vs 2.claude-opus-5(7,482 messages) andclaude-sonnet-5(3,877): 0 narration blocks.narrationblock and atextblock. The narration block stands in place of the text block, never beside it, which rules out UI collapse of a delivered text block.What would fix it, from a user's side, is either delivering the original
textblock alongside or instead of the summary on interactive surfaces, or a model-visible signal that text between tool calls will be summarised so it stops putting answers there. Until then the only complete workaround is running on Opus or Sonnet; no setting changes it, andCLAUDE_CODE_THINKING_DISPLAY_UPDATES=falseonly hides the summary line.Related: #89672 (model believes it answered), #65051 (proposed root for the cluster).
Reproduced, with a worst-case data point: a session where every interleaved-text turn was affected (100%, not intermittent), plus a clean same-day cross-model control.
Environment: Claude Code 2.1.269 (native, Linux/Debian), model
claude-fable-5, subscription auth, interactive TUI driven over a PTY. Session6bcff375-77be-456f-afca-8fe661205b7e, 2026-09-14, ~30 user turns.Numbers from the session JSONL:
tool_use, but only 4textrecords in the entire session — the first message of two turns and two turn-final messages. Every mid-turn prose message (long MR-review analyses, multi-paragraph) is absent.[thinking, thinking, tool_use]; the healthy shape[thinking, text, tool_use]occurs 3 times.Shape histogram, if useful for triage:
The fingerprint matches this issue exactly: in each affected message the second
thinkingblock is a signed, first-person paraphrase of the missing user-facing text, sitting where the text block belongs. Example — what the model streamed to the client conversation vs. what the JSONL holds:Cross-model control: five
claude-opus-5sessions on the same host, same 2.1.269, same hour — zero occurrences; all persist[thinking, text, tool_use]with full thinking text.Within-model variance: other
claude-fable-5sessions on this host range from mostly clean (Sep 7) through mostly affected (Sep 10) to the fully-affected session above (Sep 14) — consistent with the intermittency others report, but per-session rather than per-message here.Possibly relevant timing: this install is enrolled in a server-side experiment (
x-cc-atis; assignments underclientDataCacheSlotsin~/.claude.json,atis-latchrecords in every session JSONL — see #75607). A fresh assignment was cached at 11:54Z on 2026-09-14; the fully-affected session started 12:16Z the same day, while the mostly-clean fable sessions predate the cached assignments. Correlation only — I can't see the cohort semantics — but since the paraphrase blocks are server-signed, a server-side summarizer cohort would explain per-session all-or-nothing behavior.Practical impact matches #91939: turns ending in
AskUserQuestionrender as a bare question card with the entire preceding analysis invisible.(Investigation AI-assisted: evidence gathered and verified with Claude Code on the affected machine.)
I see this issue in the recently released Opus 5.5. Previously it only affected Fable 5 and Fable 5.1, but not Opus 5.0, and it's the reason I stopped using Fable models.
This bug makes experience extremely confusing to the point of making Claude Code nearly unusable.
Opus 5.5 is affected, and the Thinking docs now list it as a progress-update model. This follows up @alexkay's report. The docs' progress-updates section now reads "On Claude Fable 5.1, Claude Mythos 5.1, Claude Opus 5.5, and Claude Fable 5, the model can write a progress update between tool calls." When @milobird quoted it on 2026-09-09, Opus 5.5 was not on that list. The evidence that user-facing text is lost on Opus 5.5 is below. Switching to Opus is no longer a workaround, at least not to 5.5.
Environment (2026-09-23)
claude-opus-5-5: themessage.modelof every assistant entry in all four sessions belowClaude 2.7032.0 (6c468a) 2026-09-22T05:53:19.000Z, Code tab ("entrypoint":"claude-desktop")anthropic.claude-code-2.1.280-win32-x64showThinkingSummariesin user or project settings, and noCLAUDE_CODE_THINKING_*variable in the Desktop app's environmentReproduction: @UNIVAC-Colonel-Panic's recipe, Desktop app, session
8520ac12-…. The text was lost in 2 of 3 runs. One prompt per run, each with a fresh marker and topic:thinkingblock whose signature decodes tonarration, as @aultra described. The summaries are 296 and 314 characters, there is notextentry, and the marker gets 0 hits. Neither response had a reasoning block before thenarrationblock, so the loss does not need interleaved thinking.text. The short opening and closing lines were stored astextin all three runs.What Claude Code receives. In every session, every reasoning block is stored with an empty
thinkingfield, and everynarrationblock is stored readable. In the docs' display table, that combination isdisplay: "updates", not"summarized". With the display settings at defaults, 2.1.280 therefore appears to send thethinking-display-updates-2026-08-18beta for Opus 5.5 too, as @mserajnik described for Fable 5.1-bundle models. The client has the summary and writes it to the transcript. The Desktop app then presents it as if it were the reply.Earlier sessions, from ordinary use:
| session | surface | mid-turn text blocks missing from the transcript |
narrationblocks | reasoning blocks (all stored empty) ||---|---|---:|---:|---:|
|
48025d5c-…| VS Code extension | 5 | 5 | 35 ||
4a1dc633-…| Desktop app | 1 | 1 | 6 ||
d79dc4a1-…| Desktop app (12 short marker blocks, all delivered) | 0 | 0 | 16 |In
48025d5c-…, three of the missing updates came from one turn. The user confirmed in their next message that they had seen none of them. Their recollection, not certain, is that the VS Code extension showed nothing in their place, unlike the Desktop app's summary styled as reply text. One of thosenarrationblocks:Short markers read Opus 5.5 as unaffected.
d79dc4a1-…held 12 one-line marker blocks across 9 turns, some at the turn start and some between tool calls. Six of them followed a procedure like @williamrobotma's, with one marker at the start and one between a tool call and an AskUserQuestion. All 12 were delivered, matching his Opus 5 result. Only 1 of the 12 responses had a reasoning block before its text. A marker test alone will not show the loss on Opus 5.5. The long formatted block above does.Claude Code's own silence check counts a
narrationblock as nothing shown. Twice in48025d5c-…, anattachmentrecord{"type":"silent_turn_reminder","text":"The user hasn't heard from you in a while — say in a few words what you're doing, then continue."}was injected after anarrationblock, with notextblock in between.Sanitized structural excerpts of all four transcripts are available on request.
_Drafted by Claude Opus 5.5 (the affected model) in Claude Code, which also ran the transcript and signature checks. The reporter ran the reproduction turns, reported what was on screen, and reviewed and approved this comment before posting._
Another Opus 5.5 data point, this time through the Agent SDK (
@anthropic-ai/claude-agent-sdk0.3.263 driving Claude Code 2.1.283, macOS, subscription auth). It includes a same-script control on Opus 5 and one setting I haven't seen covered here: turning thinking off does not stop it.Setup. A folder with one short markdown file describing five cases. One prompt: "Read merge-warning.md. Draft the exact warning sentence for each case, show me all of them in a table, then ask me with the AskUserQuestion tool whether they are the right words." Fresh session per run,
settingSources: [], effort high, 6 runs per row. I recorded the first assistant message up to the AskUserQuestion call.| model |
thinkingoption | table lost | block shape ||---|---|---|---|
| claude-opus-5-5 | adaptive,
display: "summarized"| 6/6 | thinking(772) → thinking(235) → AskUserQuestion || claude-opus-5-5 | adaptive, no
display| 4/6 | thinking(0) → thinking(219) → AskUserQuestion || claude-opus-5-5 |
disabled| 6/6 | thinking(0) → thinking(0) → AskUserQuestion || claude-opus-5 | adaptive,
display: "summarized"| 0/6 | thinking(683) → text(951) → AskUserQuestion |displayoption, the reasoning block comes back empty, but the second block still carries a ~220-character summary of the missing table.narration, and every other block in the session isthinking.Impact. In one real session, three AskUserQuestion prompts in a row were each built on a table or explanation the user never saw. The user answered "where, I don't see" and then "answer me first". The model then said the table "may have been hidden behind the question box", because from its side it had been sent.
For SDK users it is worse than in the TUI. The SDK's
thinking.displaytype only allows'summarized' | 'omitted', so there's no"updates"option. Under"summarized", a narration block looks exactly like reasoning unless you decode its signature. And no setting returns the original text.Either of these would fix it:
textblock, at least right beforeAskUserQuestion, where the question depends on it.Two data points, from @aultra's
signature_labelrun over my own transcripts:Opus 5 has been affected since 11 September, though it isn't on the docs' list. Before that date it produced 0
narrationblocks (against 712 reasoning and 537 text blocks). From 11 to 19 September (Claude Code 2.1.267–2.1.278) it produced 75, across 12 sessions.AskUserQuestionoften loses the explanation written just before it: 30 of 73 calls on Opus 5.5, and 203 of 441 on Fable 5.1. The system prompt's remedy, restating important text in the final message, can't help here, because the user answers before that message exists.Windows data point: same symptom on Opus 5.5.
Environment
claude-opus-5-5, subscription authWhat happened
.jsonl: searching the file for a distinctive phrase from the answer only matches the model's own later searches for it..jsonldid it see that the text wasn't there.Impact: the turn looks like the model ignored the question, and then the model confidently says it did answer, which is confusing until you know about this bug.
Following up on my 25 July comment with a different kind of data point: not a new reproduction, but what the recommended workaround now costs downstream.
The workaround has become an architectural constraint
Because mid-turn text can be absorbed, the only reliable turn shape is: run every tool call first, then emit all substantive text in a single final block. Three months ago that was a Fable 5 precaution. With the Opus 5 and Opus 5.5 reports above, it has to be applied unconditionally -- a session cannot know in advance which model it is on, and Claude Code falls back between them silently.
That rule is now written into my global CLAUDE.md and is load-bearing on every host I run.
Where it breaks something else: any integration whose delivery is itself a tool call
I run Claude Code with the Telegram plugin, so a session can reach my phone while I am away from the terminal. The push to Telegram is an MCP tool call. The workaround requires all tool calls to precede the final text block. Therefore the message to my phone must be composed and sent before the terminal reply exists.
The two outputs cannot be mirrored. They have to be written independently, from intent rather than from the actual terminal text, and they diverge silently.
On 5 October this produced four turns in one evening where a section listing decisions waiting on me reached the terminal and never reached my phone. I found out only by comparing the two screens. Nothing in either channel reports a divergence, because both sends succeeded.
I have since added two hooks of my own to compensate, one of which compares the two at the end of a turn and blocks on a mismatch. It works, but it is a local workaround for a workaround.
Why this may be worth more than one more confirmation
No new repro to add; the July capture still stands. I am posting this because the blast radius has grown well beyond a missing paragraph.
Follow-up: still reproduces on Claude Code 2.1.291 (Windows 11,
claude-opus-5-5), and I now have a reliable headless repro.Fingerprint: a lost mid-turn reply is persisted as
thinking(empty) →thinking(signed) →tool_use, with notextblock. In interactive sessions the secondthinkingblock holds a short paraphrase of the lost reply (197–333 chars in three cases). The model's context still has the full original, but it never reaches the UI or the.jsonl. Text-only final messages survive. Example IDs:msg_011CfkqvPXvtACfohvFTuEuG,msg_011CfkqwPEc1wf5T2wJivZmH,msg_011CfkrTgSnFQkqwxEfgPDm8.Repro (about a minute per run):
with a prompt asking for an 8-step read-only system check, one tool call per step, and "before EVERY tool call write me one or two sentences saying what you found so far and what you're checking next". Then count tool-calling assistant messages in the session
.jsonlby block layout.Across 6 runs (48 steps), 17 steps had the double-
thinking, no-textlayout and 22 had text delivered. The rest had a singlethinkingand no text, which is ambiguous. Within a run it tends to start partway through: e.g. steps 1–2 delivered, then steps 5–8 all swallowed.CLAUDE_CODE_THINKING_DISPLAY_UPDATESis not the cause. In 2.1.291 the default interactive request usesthinking.display: "updates"(betathinking-display-updates-2026-08-18), which is where the paraphrase comes from. But headless runs get empty thinking blocks, so they're not in that mode, and they lose text at the same rate. Setting=1vs=0gave 8 vs 9 swallowed steps out of 24 each. The text is dropped server-side whatever display mode is requested. The display mode only decides whether a paraphrase is left behind.Correction to my earlier comment: the "user hasn't heard from you" nudge isn't required. Most lost replies didn't follow one.
Reproduces on Claude Code 2.1.288 (Claude Desktop, Linux) with
claude-opus-5-5.A reply written just before a Bash tool call was recorded as: an empty
thinkingblock, then a signedthinkingblock of 229 characters paraphrasing the reply ("Filed the stop-check toil as bug 1087 and finalized the corrected summary..."), then thetool_use, with notextblock. My actual wording appears nowhere in the session.jsonl; grepping its distinctive phrase returns 0 hits. Replies in later turns of the same session were recorded normally.It matters beyond the visuals: a tool of ours reads the last reply before a call (a close report that must carry the operator-facing summary), found only the paraphrase, and had to treat it as "no reply text". It never reposts thinking, so it closed on a separate message field and warned. The operator likely never saw the summary either.