Assistant text emitted mid-turn (after a tool result) is silently dropped from both the TUI and the session transcript
Summary
When an assistant turn emits text after a tool result and before the next tool call
("mid-turn continuation text"), that text is silently discarded: it never renders in the
TUI and it is never written to the session JSONL. The text demonstrably reaches Claude
Code — the model quotes it verbatim from conversation context on later turns — so this is
neither a model-side omission nor an API streaming failure.
Text emitted at the start of a turn (before any tool call) is unaffected: it renders and
persists normally, even multiple long paragraphs immediately preceding AskUserQuestion.
The result is that a user watching the session sees the agent jump straight from a tool
call to the next tool call or question panel, with the explanation connecting them simply
gone — and the transcript offers no recovery, because the text was never stored.
Reproduction
Deterministic — 4/4 attempts across two clients and two versions.
- Start
claudein any project. - Prompt:
> Read any file, then in the SAME turn: write me a 3-paragraph explanation of what you
> found as text, and immediately after call AskUserQuestion asking me to pick between
> two follow-ups. Do NOT put the explanation inside the question. The text MUST be
> emitted before the AskUserQuestion call in the same turn.
- Observe the screen: the question panel appears with no explanation above it.
- Inspect the session transcript:
jq -r 'select(.type=="assistant") | [.timestamp, (.message.content | map(.type) | join(","))] | @tsv' \
~/.claude/projects/<project-slug>/<session-id>.jsonl
The turn persists as thinking, thinking, tool_use(AskUserQuestion) — no text block.
Observed vs expected
Observed: mid-turn text is absent from the display and absent from the transcript;
sibling blocks of the same response (thinking, tool_use) persist normally.
Expected: the text renders above the tool UI and is written to the transcript as atext block, the same way turn-initial text is.
Evidence
Two sessions, same project, same day. Timestamps are from the on-disk records.
A. Claude Code 2.1.210, cmux 0.64.19 (4 runs)
| Run | Turn shape | Rendered | In transcript |
|---|---|---|---|
| 1 | Read → 3 paragraphs → AskUserQuestion | no | no |
| 2 | intro line → Read → 3 paragraphs → AskUserQuestion | intro only | intro only |
| 3 | intro line → Read → 3 paragraphs → Bash | intro only | intro only |
| 4 | 3 paragraphs → AskUserQuestion (turn-initial, no prior tool) | yes | yes |
Run 3's persisted sequence: thinking → text(intro) → tool_use(Read) → tool_result →. The paragraphs generated between the tool result and
thinking, thinking → tool_use(Bash)
the Bash call are in neither the display nor the file.
Run 4 is the control: same length, same following tool, but emitted turn-initially — it
rendered and persisted. Tool type and text length are therefore ruled out; position
within the turn is the trigger.
B. Claude Code 2.1.211, plain Terminal.app (1 run, no terminal multiplexer or wrapper)
Persisted sequence: thinking → text("I'll read one of the untracked scratch files… then.
give you the 3-paragraph write-up followed immediately by the question") →
tool_use(Read) → tool_result → thinking, thinking → tool_use(AskUserQuestion)
The announced 3-paragraph write-up appears nowhere on screen or on disk. The turn-initial
intro text is the only text block in the entire session file.
Proof the text reached Claude Code (session A): on subsequent turns the model
reproduced the dropped paragraphs verbatim from its conversation context. Claude Code held
the text in memory, then neither drew it nor wrote it.
Environment
- Claude Code 2.1.210 and 2.1.211 (both affected)
- macOS 26.5.1 (Darwin 25.5.0), arm64
- Model: Fable 5 (
claude-fable-5), xhigh effort, Claude Max - Terminals: cmux 0.64.19 and stock Terminal.app — not client-specific
- No API errors, retries, or 529s during any run
Why this isn't the existing (closed) issues
- #24691 / #24733 — "streaming text disappears when followed by tool calls":
display-only, and reported as intermittent. Here the text is missing from the
transcript too, and reproduces on demand.
- #21751 — "assistant text never written to transcript": correlated with
file-history-snapshot events and percentage-based. Here it is positional and
deterministic, with a clean control (turn-initial text always survives).
- #57819 — non-streaming fallback writing bundled multi-block records: those records
retain the text on disk (recoverable). Here nothing is recoverable.
- #29937 / #37076 — tmux rendering corruption: no multiplexer involved; and
rendering corruption doesn't explain a missing transcript record.
The new information is the positional determinism (mid-turn drops, turn-initial
survives), the dual display+transcript loss, and the context retention — which
together localize the fault to Claude Code's handling of continuation text blocks within a
turn, downstream of the model and upstream of both the renderer and the transcript writer.
Impact
The agent's explanation of what it found — often the most valuable output of a turn — is
the exact thing destroyed, while tool calls survive. Users must interrupt and ask for the
content again, and it cannot be recovered afterward from the transcript. The only reliable
workaround is to restructure every turn as "all tool calls first, then one final text
block," which forfeits interactive commentary.
Suggested direction
Treat text blocks the same regardless of their index within a turn: emit continuation
text to the renderer when it arrives, and persist it to the JSONL alongside its siblingthinking/tool_use blocks — rather than letting the next tool block's arrival supersede
the pending text.
Other observation (possibly unrelated, noted while diagnosing)
The assistant record containing an AskUserQuestion tool_use is not written to the
transcript until the question is answered or declined; it then lands carrying its original
generation timestamp. Other records within the same turn flush immediately. This makes
in-flight sessions look truncated on disk.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗