[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.
12 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.
Additional controlled evidence from the desktop app (macOS, Claude 1.25927.0 (003700), 2026-08-05/06), independently corroborating the OP and adding sentinel-based verification:
Bash(echo) → unique sentinel sentence → Bash(echo), never-reused sentinels, user screenshot-verification after each turn. claude-fable-5: 7/7 sentinels lost across two independent sessions (one fresh, one 12h/7.5MB — session age irrelevant), batching every time ("Ran 2 commands" ×4, "Ran 3 commands" ×1 with two sentinels lost in a single turn). Text present in the session JSONL in all our cases. Controls: text before the first call and after the last call rendered 10/10 across both sessions. Screenshots available on request.Exposure datapoint: across one user's 355-transcript archive (2026-07-01 → 2026-08-06), 1,275 of 1,385 AskUserQuestion turns carry the at-risk shape (prose between/around tool calls in the same turn) — exposure, not confirmed losses, since display state isn't recoverable from transcripts.
Also ruled out on our side: overlay/occlusion/scroll-lock (#57691, #62390, #64776, #23862, #30422) — the text is absent after minimizing cards and scrolling, not covered. Possibly related mechanism-wise to #76760 (no-text-block variant with stripped narration-channel thinking blocks); our archive shows both patterns.
Confirming on a third surface: the claude.ai/code remote-session web view (not just desktop GUI + CLI).
Instance today (2026-08-11, Fable 5, session
session_01HsFAeM5WHPJNdFEP8g5Tgi): a turn structured astool call → text (full substantive paragraph) → tool call → short trailing textrendered only the trailing status line ("Tab closed."). The interleaved paragraph — the actual answer — never appeared in the conversation view, though it is present in the transcript. The model then journaled having responded; the user experienced no response.From the user's side: "this happens sometimes, when you think you've responded but there's nothing in the conversation here… it happens quite a lot." The failure is especially costly on remote sessions because there is no JSONL the user can consult — the rendered web view is the only artifact they have, so dropped text is indistinguishable from the assistant ignoring them.
Current workaround we've adopted model-side: keep substantive content out of interleaved positions and repeat anything important in the turn's final text block.
(Comment drafted by the Claude instance involved, posted from the account of the user who hit the bug.)
Still reproducing on 2.1.233 (macOS), both surfaces at once: Ghostty CLI and the desktop app's Code tab viewing the same local session.
Sequence in one turn: Bash tool call → ~15 lines of assistant text (a direct answer to five user questions) → SendMessage tool call → one closing sentence.
Real cost: the user asked "did you not get my messages?" because the only visible output was the closing sentence. For an orchestrator that answers while tools run, this makes every mid-turn answer invisible. Workaround we're using: put any user-facing answer as the final text after all tool calls, or in a turn with no tool calls.