[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)

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

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

  1. Start a session (desktop app or CLI)
  2. Ask for a multi-step task and request narration between steps (e.g. "investigate X, explain what you find between each command")
  3. The model emits: text → tool call → text → tool call → text
  4. 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.

View original on GitHub ↗

12 Comments

christian-lallo · 4 months ago

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:

  • v2.1.152: interleaved assistant text was missing from the display but present in the session JSONL — a pure rendering defect, as originally described.
  • v2.1.170: in a freshly reproduced instance, the interleaved text blocks are missing from the display and absent from the session JSONL. The turn's other content persists normally (turn-leading text, all tool_use entries, closing text) — only the text blocks between tool calls are gone. The persisted sequence reads: text → tool_use → tool_use → tool_use → text, with no interleaved text entries.

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 --resume context 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.

christian-lallo · 4 months ago

<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

mdickinson · 4 months ago

Is this the same issue as described in #67029, #66960?

christian-lallo · 4 months ago

@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.

ArtemShaban · 4 months ago

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.

odedd · 3 months ago

same here

brian-kilpatrick · 3 months ago

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

  • Claude Code 2.1.199, macOS (Darwin 25.4.0), terminal CLI
  • Model: claude-fable-5 — consistent with the Fable correlation others reported

Repro (long agentic turn, ~dozens of tool calls)

  1. Agent was mid-task (multi-PR bug-fix session, lots of Bash/Edit tool calls).
  2. I sent a steering message mid-turn ("leave anything AI-initiative-related for later").
  3. The model emitted a standalone acknowledgment text block between two tool calls — confirmed present in the session .jsonl (grep finds the full "Noted — I'll leave everything tied to…" block).
  4. Nothing rendered in the terminal. From my side there was zero indication the directive had been received; the acknowledgment only became visible when the model restated it in the turn's final message, much later.

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.

mafresh-max · 3 months ago

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_widget call, 4 interleaved assistant text blocks, model claude-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.

christian-lallo · 2 months ago

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-8 until mid-day, then was switched to claude-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 text records 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 text records.

Verification pitfall for anyone checking their own transcripts: naive grep -c false-positives — your verification commands themselves persist as tool_use records containing the search phrases. Require the phrase inside a type:"text" content block of an assistant record.

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.

johnlawrimore · 2 months ago

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:

  1. Independent expanded-batch corroboration: we hit this without knowing this thread existed — expanding the collapsed "Ran N commands" row shows only the tool rows; the interleaved text is absent there too. Matches the OP's step 4 exactly, from a separate setup.
  1. Sentinel methodology, screenshot-verified: pre-planned turns shaped 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.
  1. Extends the cross-model A/B upthread to Opus 5: our clean comparison was claude-opus-5 (not 4.8) — identical shapes, same machine, same day: 7/7 sentinels rendered, and no batching ever occurred (every call rendered as its own row). Combined with the 4.8 result above, loss has correlated 1:1 with batching in every observation across four sessions and three models.

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.

swombat · 2 months ago

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 as tool call → text (full substantive paragraph) → tool call → short trailing text rendered 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.)

alanxchen85 · 2 months ago

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.

  • CLI: shows "Ran 1 shell command", the SendMessage result line, and the closing sentence. The 15-line answer is gone.
  • Desktop app: the same text is folded under "Ran 3 commands, used 2 tools ›" with no way to see it.
  • Session JSONL has the text.

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.