[Regression bug] TranscriptEvent write delay: tool_use event not written to session.jsonl until the tool_use_result is received.
Status Closed — not planned
Reported on v2.1.119
Maintainer reply None cached
Workaround ✓ Mentioned in thread ↓
Activity 10 comments · opened May 12, 2026 · closed Aug 29, 2026
Bug Description
there is a regression I notice with your transcript event writes. the current version does not write the AskUserQuestion event to the session .jsonl on disk until after the user provides an answer. older versions (2.1.119 verified) do as expected which is write the AskUserQuestion event to disk immediately upon prompting.
Environment Info
- Platform: win32
- Terminal: windows-terminal
- Version: 2.1.139
- Feedback ID: 0b70a2ea-4db7-46a6-9927-d99e7736ca14
The prior behavior is needed so external tooling can notify the user that interaction is required to continue.
repro steps:
- new session
- user prompt:
qna prompt test: ask me a simple question - wait for the question to be shown on screen
- inspect the session
.jsonl, AskUserQuestion tool_use event is missing - back in the session, respond to the question
- check the
.jsonland the AskUserQuestion tool_use event will now be written, using the original ask timestamp (not the timestamp in which it's finally written to disk)
Showing cached comments. Read the full discussion on GitHub ↗
9 Comments
it seems like perhaps the latest transcriptEvent is not being flushed properly, as it seems other events are being delayed also
Same on Linux with version 2.1.138. On my end, this breaks a relay that tails the transcript.
Also affected by this.
🔧 Root Cause Analysis & Fix Proposal
Problem
AskUserQuestiontool_useevents are not written tosession.jsonluntil the user responds. This breaks external toolchains that tail the transcript for real-time event detection.Root Cause
The transcript flush logic was changed to batch events —
AskUserQuestionevents are held until the correspondingtool_resultarrives, then both are written together. This breaks the real-time event stream contract.Suggested Fix
Separate event creation from answer association:
Impact
I also see that now token usage as reported in the
.jsonldoes not match theclaude.exereported amount most of the time, likely because the transcript events are being withheld (not written) upon delivery anymore.This is a serious regression. When a MCP or tool call fails due to a tool hang, the toolUse event is never written to .jsonl. Then, if you interrogate Claude about the hang from another session , it will claim that you canceled before the tool was ever called. Because it never writes the tool call to jsonl so it doesn't think it happened.
This is not stale. it still happens with all tool calls not being flushed to disk until after the toolUseResult is available.
another nasty side effect of this bug is if your session closes before the flush, the history is lost when you resume. so it will effectively rewind your conversation to before the unflushed events took place.
Confirming this is still present in v2.1.201 (Windows), and a note on a partial write that makes it look "half-fixed".
We build an external daemon that tails the session
.jsonlto detect when an interactive session is parked on anAskUserQuestionand needs input. This regression breaks that detection exactly as described: while the modal is parked, the assistant turn containing theAskUserQuestiontool_useis not written to disk. It only appears after the user answers or cancels, batched together with thetool_resultand backdated to the original invocation timestamp.Reproduced on 2.1.201:
AskUserQuestion. The transcript tail remains frozen at the lastuserrecord for the entire time it is parked (observed for 30+ minutes); thethinking/text/tool_userecords for the parked turn are absent.tool_result; thetool_useretains its original invocation timestamp, showing that the completed message was buffered rather than written when it was rendered.**Possible source of confusion — a partial record that is not the fix:** On 2.1.201, a separate
{"type":"ai-title","aiTitle":"...","sessionId":"..."}record is written while the modal is parked. This is the long-standing session-title record emitted via an independent code path. It is not thetool_useevent and does not contain the question or options, so it does not restore the real-time event stream. External tools still cannot see the pending question from the transcript.Note that 2.1.200's "AskUserQuestion no longer auto-continues by default" change makes this worse in practice: modals now remain parked indefinitely instead of automatically continuing after ~60 seconds of inactivity, so the window during which the pending question is invisible to external tooling is now unbounded.
+1 on the suggested fix (write the
tool_useevent withanswer: null, flush it immediately at invocation, and associate the answer separately). That restores the real-time contract.Workaround for others encountering this: A
PreToolUsehook configured forAskUserQuestionreceives the full{questions, options}payload on stdin at tool dispatch—before the modal parks and independently of the broken transcript flush. Capturing it there (and clearing it on the correspondingPostToolUseevent or when the answer arrives) is a reliable out-of-band substitute for the transcript event until the flush behavior is fixed. It is not a fix for the transcript contract itself, but it does unblock external detection today.Environment:
claude2.1.201 (Windows 11; also observed on 2.1.195).CLAUDE_CODE_SKIP_PROMPT_HISTORYunset. Interactive CLI (not-p/headless).