[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).
Showing cached comments. Read the full discussion on GitHub ↗
7 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.