[BUG] Assistant text between tool calls is not rendered in GUI or CLI, though fully persisted in session JSONL (regression of #41814 family, amplified by Fable 5)
Description
When the assistant emits text blocks between tool calls within a single response turn, that text is not rendered anywhere in the UI — neither in the desktop app nor the CLI. The turn's tool calls are collapsed into a single "Ran N commands" summary line; expanding it shows only the command labels. Turn-leading text (before the first tool call) renders normally, and the turn's closing text renders normally. Only interleaved text is lost from display.
The text is fully persisted in the session JSONL — this is purely a rendering defect, not data loss. But the user experiences the assistant as silent through long multi-step sequences, including progress updates and intermediate findings the model emitted specifically to keep them informed.
Steps to reproduce
- Start a session (desktop app or CLI)
- Ask for a multi-step task and request narration between steps (e.g. "investigate X, explain what you find between each command")
- The model emits: text → tool call → text → tool call → text
- Observe: only the first and last text blocks render; the middle blocks are absent in both surfaces, even after expanding the collapsed tool group ("Ran N commands ▸")
Expected behavior
Interleaved assistant text renders in reading order between (or alongside) the tool calls it annotates.
Actual behavior
Interleaved text is silently dropped from display in both the desktop GUI and the CLI. Ctrl+E / expansion does not reveal it. The JSONL transcript contains it intact.
Environment
- Claude Code v2.1.170 (also observed on 2.1.152)
- macOS (Darwin 25.3.0), desktop app + CLI under tmux
- Model: claude-fable-5 (1M context)
Notes
- Related: #46110, #41907 — closed as duplicates of #41814, fixed in 2.1.101. This is either a regression or a surviving variant: those reports centered on tool calls/old output being hidden; this one is specifically interleaved assistant text being unrecoverable in the display while present in the transcript.
- Fable 5 amplifies the impact: its documented output style emits frequent short updates between tool calls, so sessions on Fable hit this constantly. The model appears silent or terse when it is actually narrating.
- Screenshots of the GUI rendering (collapsed group with missing interleaved text) to follow in a comment.
Showing cached comments. Read the full discussion on GitHub ↗
9 Comments
Correction and escalation on the persistence claim in the original report.
After filing, I re-verified the transcript persistence with exact-phrase searches against the session JSONL rather than a loose proxy match. Result:
So on the current version this appears to have crossed from a display bug into data loss: the interleaved text never reaches the transcript, so it is unrecoverable (not available to
--resumecontext reconstruction, transcript export, or any downstream tooling reading the JSONL).Possibly relevant: the 2.1.170 release notes include a fix for "sessions not saving transcripts" in certain launch contexts, so transcript-persistence code was modified in this release window.
Happy to provide repro details. Screenshots of the rendering side are attached above/below by the account owner.
<img width="1507" height="881" alt="Image" src="https://github.com/user-attachments/assets/48cfb085-7581-4de3-9ec1-d9618feebb9f" />
Desktop GUI: multi-tool turn collapsed to 'Ran 3 commands' — interleaved narration absent
Is this the same issue as described in #67029, #66960?
@mdickinson #67029 looks like the same defect, surfaced in a specific (and high-consequence) case — the swallowed text immediately precedes an
AskUserQuestion, so the user is asked to decide without the context the model emitted. Same version, same model, same lane: text blocks adjacent to tool calls dropped from display.#66960 may be partially downstream of it: "long stretches of total silence during tool calls" is exactly how this bug presents to the user when the model is in fact narrating between calls. We can't verify their case — and notably, on 2.1.170 nobody can after the fact: as documented in the comment above, the interleaved text is now also absent from the session JSONL, so "model never spoke" and "renderer dropped it and the transcript lost it" are indistinguishable post-hoc. That's arguably the strongest reason to treat the persistence regression as the priority half of this issue — it removes the ability to audit reports like #66960 at all.
Happy to consolidate into whichever issue you prefer as canonical.
Confirming on macOS 26.5.1, Terminal.app inside tmux 3.6b, Claude Code 2.1.175 (CLI), model claude-fable-5.
Mid-turn text blocks (in our case: step-by-step instructions for the user, emitted between Bash/Edit tool calls) were never rendered in the CLI, while turn-initial and turn-final text rendered fine. Verified present in the session JSONL. Hit this twice in two days; the user only discovered it when referencing instructions they never received.
Workaround we adopted: instruct the model to place anything user-critical at the very end of the turn, after the last tool call.
same here
Another repro, with one new data point: on 2.1.199 the loss is render-only — the dropped text IS present in the session JSONL (unlike the on-disk loss reported on 2.1.170+), it just never renders in the terminal.
Environment
Repro (long agentic turn, ~dozens of tool calls)
.jsonl(grepfinds the full "Noted — I'll leave everything tied to…" block).Matches #67708's consequence too: if I'd pressed the model about it, it would have "insisted it answered" — because from its perspective it had.
Impact: mid-turn steering feels ignored; the only reliable channel is the end-of-turn message. Happy to share the session JSONL excerpt if useful.
Confirming on Claude Code Desktop v2.1.172 (macOS 26.2 / Darwin 25.2.0) — with a variant that appears worse than the OP:
In a long multi-phase turn (7 Bash tool calls + one MCP
show_widgetcall, 4 interleaved assistant text blocks, modelclaude-fable-5), all 4 text blocks before/between tool calls were dropped — not only in the UI render: they are also absent from the local session JSONL (~/.claude/projects/<cwd>/<session>.jsonl). Only the text block after the final tool call survived (rendered + persisted).Shorter turns in the same session (leading text + 1–3 tool calls) rendered and persisted fine, so in our case it correlates with long multi-phase turns rather than affecting all interleaved text.
Practical impact of this variant: since the JSONL is missing the blocks too, there is no recovery path via transcript — the content (a final report the user was waiting for) was silently and irrecoverably lost.
Within-session A/B on 2.1.202: Opus 4.8 interstitials persist, Fable 5 interstitials lost on-disk — the data-loss variant is present in the current release and the Fable correlation holds under a controlled comparison.
Environment: Claude Code 2.1.202, CLI inside tmux, macOS (Darwin 25.5.0). Single continuous session that ran
claude-opus-4-8until mid-day, then was switched toclaude-fable-5(~12:03 local).Fable side: a turn shaped text → Bash → text → Bash → text → Bash → text lost both interstitial blocks (one short, one ~700 words carrying the analysis the turn existed to produce). Display collapsed to "Ran 3 commands"; the blocks are absent from the session JSONL — verified by multiple distinctive exact phrases, zero assistant
textrecords contain them. Turn-opening and turn-final blocks rendered and persisted normally.Opus side (same session, ~40 min earlier): three probed interstitial text blocks from comparable multi-tool turns all persisted as normal
textrecords.Verification pitfall for anyone checking their own transcripts: naive
grep -cfalse-positives — your verification commands themselves persist astool_userecords containing the search phrases. Require the phrase inside atype:"text"content block of anassistantrecord.Updates to the thread: (1) the data-loss variant (previously 2.1.172; 2.1.199 was reported render-only) is present in 2.1.202; (2) the Fable-5 correlation survives a same-session, same-version, same-environment comparison — this looks model-conditional, not just version-conditional.
User-side screenshot of the collapsed turn available; timestamps available if a maintainer wants to correlate server-side.