Assistant text emitted before a tool call in the same turn (esp. AskUserQuestion) is intermittently never rendered to the user
Environment
- Claude Code CLI 2.1.215, Windows 11 Pro (10.0.26200), PowerShell/Git Bash
- Occurs with plugin-driven workflows using AskUserQuestion, but the mechanism is generic
Summary
Assistant text that precedes a tool call within the same assistant turn is intermittently not displayed to the user. The most damaging shape: the assistant renders a substantive deliverable (a report/table several KB long) and then calls AskUserQuestion in the same turn — the user sees ONLY the question dialog, with the entire deliverable silently dropped. The user is then asked to choose between options whose context they never saw.
Empirical shape table (accumulated over ~8 occurrences across two weeks)
| Turn shape | Outcome |
|---|---|
| tool calls → text (terminal, no further tool call) | text rendered reliably |
| text → AskUserQuestion (no preceding tool calls) | usually rendered — but we now have one confirmed loss in this shape too |
| tool calls → text → AskUserQuestion | text intermittently lost (most common failure) |
| text → AskUserQuestion that times out / is interrupted | whole turn's text lost |
Repro (as reliable as we've found)
- In one assistant turn: call any tool (e.g. a file read or MCP query), then emit ~2-4 KB of markdown (tables/headings), then call AskUserQuestion.
- Intermittently, the markdown between the tool result and the AskUserQuestion never appears in the transcript UI — only the question dialog renders.
- Same content re-emitted in a turn that ends in plain text (no trailing tool call) renders fine.
Impact
Any workflow that presents a deliverable followed by a decision prompt in one turn (report → options) can silently hide the deliverable. We rewrote our plugin's rules three times assuming an instruction-following defect before isolating it to rendering: only turn-terminal text appears to be display-guaranteed; text between/before tool calls appears to be treated as droppable intermediate narration.
Expected
All assistant text in a turn is rendered in order, regardless of subsequent tool calls in the same turn.
Showing cached comments. Read the full discussion on GitHub ↗
11 Comments
Correction to the shape table from further analysis of the two 2026-07-20 occurrences, based on the user's firsthand account:
The second occurrence was a turn shaped text → single AskUserQuestion with NO preceding tool calls in the turn — previously believed to render reliably. The user saw only the question dialog; the ~2KB of markdown before it never displayed. We initially suspected the user's subsequent interruption of the dialog tore down the turn's text (the timeout-loss shape), but the causality is backwards: the user interrupted the dialog because the text was already missing when the dialog appeared. Text is expected to render before the tool call executes, so a later interruption cannot explain a pre-existing absence.
Net: the loss is not limited to text sandwiched between tool calls. A single trailing AskUserQuestion appears sufficient to drop ALL preceding text of the turn, at least intermittently, even when the text opens the turn. Both 2026-07-20 occurrences involved exactly one AskUserQuestion call — no merged/duplicate question dialogs were involved.
Reproducing on macOS (darwin 25.5.0) with CLI 2.1.217 — so this is not Windows-specific and still present in the latest version. Multiple occurrences over two days, all in plan mode, with both
text → AskUserQuestionandtool calls → text → AskUserQuestionshapes. Model: claude-fable-5.Two findings that may help narrow the bug surface:
.jsonl. I grepped distinctive phrases from two dropped messages and both were present in~/.claude/projects/<project>/<session-id>.jsonl. So the loss happens purely in the display layer — both the live TUI and the transcript view (ctrl+o) skip the text, but persistence is intact. Recovery workaround:``
bash
``jq -r 'select(.type=="assistant") | .message.content[]? | select(.type=="text") | .text' <session>.jsonl | tail -50
Controlled A/B data confirming the model correlation suggested above, with transcript-level checks.
Environment: Claude Code CLI 2.1.220, macOS (darwin 25.5.0), iTerm2, interactive session (not plan mode). Models compared: claude-fable-5, Sonnet 5, Opus 5.
Method: blind probe protocol run in fresh sessions per model. Each probe reply = plain text, then an AskUserQuestion in the same turn, with the tools-before-text variable controlled (none / one Read / one Bash). Short class = 130-240 chars; long class = ~900-1100 chars. The user scored visibility live via the question box itself; the session then greped its own
.jsonlfor each probe marker.Results:
| Model | Class | Probes | Visible to user | Marker present in session .jsonl |
|---|---|---|---|---|
| Sonnet 5 | short | 3 (none/read/bash) | 3/3 | 3/3 |
| Sonnet 5 | long | 3 | 3/3 | 3/3 |
| Opus 5 | short | 3 | 3/3 | 3/3 |
| Opus 5 | long | 3 | 3/3 | 3/3 |
| Fable 5 | short | 3 | 0/3 | 0/3 (not recorded at all) |
| Fable 5 | long | 3 | 0/3 | 3/3 (recorded, never rendered) |
An earlier 20-probe run on Sonnet 5 (10 short / 10 long, same text→AskUserQuestion shape) was also 20/20 visible and 20/20 recorded.
Notes that may help triage:
Happy to share the probe prompt files if useful for a regression test.
Another occurrence, this time on 2.1.220 (latest as of today), macOS 15 (Darwin 24.6.0), kitty terminal.
The shape was the second row of your table: a text-only explanation of roughly 1.5 KB followed directly by AskUserQuestion in the same turn, with no earlier tool calls in that turn. The entire text block never rendered. The user's next message was literally "what lesson? i don't see it". So that row is now a confirmed full loss on a second platform and on the current release.
Some history that may help triage: #30422 (last line truncated before the widget) was closed completed in March 2026, and #65841 (prompts never rendering) was closed not planned in July. This issue looks like the surviving superset of both.
Workaround we now run, in case it helps others: a PreToolUse hook on AskUserQuestion that parses the session transcript jsonl, measures the contiguous assistant text since the last tool event, and blocks the call once per turn when that segment exceeds a threshold (~350 chars). The block message tells the model to either end the turn with the content and ask in the next turn, or write the content to a file first. The retry is allowed so it cannot loop. Since the loss is render-only, dropped text is also always recoverable from the transcript jsonl or /export.
Fix direction, from the outside: the behavior is consistent with only turn-terminal text being display-guaranteed. Either flushing pending assistant text blocks to scrollback before mounting the interactive widget, or re-rendering the preceding blocks when the widget resolves, would close this.
Disclosure: this comment was drafted with AI assistance inside a Claude Code session; the occurrence described above was observed directly by the human user, and the hook workaround was verified end to end before posting.
Another reproduction, adding a platform not yet represented in this thread: Linux under WSL2.
Environment
Occurrence (2026-08-02)
Turn shape was the
text → AskUserQuestionrow: a multi-paragraph explanation followed by an AskUserQuestion call in the same turn. Only the question dialog rendered; the explanation never appeared. Confirmed by comparing the session transcript against a screenshot of what the user actually saw — the text was authored, and was not displayed. Consistent with the render-only diagnosis in the comments above.Two data points that may help triage
Model correlation matches the A/B results already posted: not observed with Opus models in this same CLI version and terminal. Sonnet and Haiku were not tested here.
Impact, restated from the user's side: the practical harm is that a question dialog arrives with none of the reasoning the model wrote for it. The user answers without the context, and reasonably concludes the model gave no explanation at all — which also misleads them about the model's behavior, not just the UI's.
Confirming reproduction on macOS — this is not Windows-specific.
Environment
Observed
Same shape as the OP's most common failure:
tool calls → ~2-3 KB markdown (headings + tables) → AskUserQuestionin a single assistant turn. The markdown between the last tool result and the question dialog was truncated to a single line fragment immediately above the dialog — the rest was never rendered. The user was prompted to approve a design they had never been shown.Hit this twice in one session (both times the turn contained tool calls before the text). Re-emitting the identical content in a turn that ends in plain text (no trailing tool call) rendered it in full, matching the OP's observation that only turn-terminal text appears display-guaranteed.
One additional detail that may help triage: in our case the swallowed text was not fully invisible — its first line rendered as a truncated fragment directly above the AskUserQuestion dialog, suggesting the renderer began emitting the text block and was cut off by the dialog paint rather than the block being dropped before rendering.
Suggest removing/expanding the
platform:windowslabel — this reproduces on macOS with the same turn shapes.Block-level evidence for the "not recorded at all" bucket in the A/B table above: in our sessions the lost text arrives from the API as signature-bearing
thinkingblocks, not astextblocks. It is not purely a display-layer drop.Environment: CLI 2.1.220, macOS (darwin 25.5.0), claude-fable-5 (high reasoning effort), interactive sessions inside a PTY we can capture out-of-band.
What we found
thinking, thinking, tool_use— one thinking block more than usual — with the extra block carrying a genuine APIsignature. Messages with no authored mid-turn text never have the extra block. Perfect correlation across dozens of messages. Since the CLI persists thinking blocks with emptythinkingcontent (signature only), the text is unrecoverable from the JSONL — which would read as "not recorded at all" if you grep for the marker, when it is actually recorded as an empty-content thinking block.queue-operationentry in the JSONL). n=1 on that trigger, but a second affected session flipped with no queue injection, so injection is at most one of several triggers. #80136 reports onset after a mid-session/modelswitch — also a mid-conversation context perturbation.thinking, thinking, tool_use(AskUserQuestion)with ~1KB of output tokens and no text block — yet the model quoted the "lost" deliverable verbatim in a later turn, so the content remained in its live context.Implication for triage
There appear to be two distinct mechanisms behind identical user-facing symptoms, and the thread already contains evidence of both:
Happy to provide sanitized JSONL excerpts (block structure, signatures lengths, timestamps) if useful.
Following up on my earlier WSL2 report, where I flagged as an unverified recollection that this is not limited to
AskUserQuestion. I can now upgrade that to a measured claim: today it reproduced with a plainEdittool call, verified against the session transcript, in a session where the trailing tool was neverAskUserQuestion.Environment
The occurrence
Turn shape: prior tool calls → multi-paragraph analysis the user had explicitly asked for (~2 paragraphs plus a recommendation) →
Editcall on a markdown file, all in one assistant message.What the terminal rendered: the previous turn's text, the tool-use summary line ("Searched for 1 pattern, listed 1 directory, ran 1 shell command"), the
Editdiff block, and the next assistant message. The analysis between them never appeared.The user's next message was: "did you reply something after that part? Did you not reply anything or is it the tool-call-swallows-output bug?" — i.e. from the user's seat, "the model said nothing" and "the renderer dropped it" are indistinguishable.
Transcript evidence: matches the thinking-conversion mechanism, with
EditThis is the block structure @nircoh-onyx described, so I can corroborate that mechanism on a non-
AskUserQuestiontool. Comparing the failing message with a control from the same session, same model, same trailing tool type, ~11 minutes later:| | Failing message
msg_011CdfkFHpkXL7rJNzVfXpcW(11:36:41Z) | Controlmsg_011Cdfm5uLXHiG6cVSJ8MrQq(11:47:36Z) ||---|---|---|
| Block sequence |
thinking,thinking,tool_use:Edit|thinking,text(197),tool_use:Edit,tool_use:Bash|| Signature lengths | 4912, 2696 | 5720 |
|
textblock | absent | present || Rendered to user | no | yes |
|
output_tokens| 2690 | 2063 |An extra signed
thinkingblock sits in the exact slot thetextblock occupies in the control. Boththinkingblocks persist with empty content, so the authored text is unrecoverable from the JSONL — agrepfor it returns nothing, which reads as "never sent" rather than "dropped". Consistent with the "not recorded at all" bucket in the A/B table above, but here with a length class (multi-paragraph) that the earlier table put in the render-only bucket, and with an ordinary editing tool rather than an interactive widget.Two findings that may narrow triage
1. It did not latch in this session. @nircoh-onyx reported the conversion latching per session from a precise timestamp onward. Mine did not. Over a 90-minute session I get 22 messages shaped
thinking, thinking, …, tool_use(no text block) interleaved with 25 shapedthinking, text, …, tool_use(text present and rendered), alternating throughout — e.g. 11:35:54 fine, 11:36:41 lost, 11:36:55 fine. So per-message intermittency and per-session latching are both real; a fix keyed only to a latch/trigger event would miss this.Caveat on that count: only the 11:36:41 message is independently corroborated as having carried user-facing text (user reported not seeing it; model reported writing it). Some of the other 21 may be genuine two-segment reasoning. I offer the ratio as a shape census, not as 22 confirmed losses.
2. The conversion only occurred mid-message. In this session, zero messages ended with
thinking, thinkingand no tool call — every double-thinkingmessage had atool_useafter it, and all 12 turn-terminalthinking, textmessages rendered. That is more specific than "trailingAskUserQuestiontriggers it": the affected slot is text followed by anytool_usein the same message. In this session the trailing tool wasBash,Read,Write,Edit,ToolSearch, and onceAskUserQuestion— the widget is not required.Why this is worse than the AskUserQuestion case
With
AskUserQuestionthe user at least knows a turn happened and can ask what it was about; the dialog is a visible anchor. With an ordinary tool call there is no anchor at all:That last point is the ask: even absent a full fix, a client-side signal — e.g. surfacing "this message contained N thinking blocks and no text" or a marker when a signed thinking block carries empty content in the text position — would let both the user and the model detect the loss instead of silently diverging.
Disclosure: drafted with AI assistance inside a Claude Code session, at the request of the human user who experienced the occurrence. The transcript block structure, signature lengths, and shape census above were read directly from the session JSONL; the rendering failure was observed by the human user. Message content is withheld as it is from a private project.
Same issue here — adding a data point.
Environment: Claude Code CLI 2.1.223, Windows 11 Pro (10.0.26200).
tool calls → text → AskUserQuestionin the same turn loses the preceding text almost every time in our sessions (content is Traditional Chinese markdown, typically 1–4 KB with headings/tables).questiontext and option descriptions, and (b) deliver the full explanation as a separate file — i.e. we treat the popup as required-to-be-self-contained because prose in the same turn cannot be trusted to render.Happy to provide session JSONL excerpts if useful.
Same issue here , it's been there for a long time
This is by far the craziest bug open in Claude Code today. I experience it daily.
User requirement: I type a message to Claude, when Claude responds I see that message 100% of the time
Seems pretty simple but this has been ongoing for ~1.5 months or more.
#67071 #65662 and a bunch of other issues relate to this.