Transcript writer intermittently drops assistant text blocks ("mute windows"); thinking/tool_use of the same messages persist
Environment
- Claude Code versions: observed on 2.1.206, 2.1.211, 2.1.212 (CLI, linux x86_64, Ubuntu / kernel 6.8)
- Models: claude-fable-5 and claude-opus-4-8 (not model-specific)
- Non-interactive evidence gathered by line-by-line inventory of
~/.claude/projects/<slug>/<session_id>.jsonlfiles across 4 concurrent sessions
Summary
The transcript writer intermittently stops persisting assistant text content blocks while continuing to persist thinking and tool_use entries of the same assistant messages. We call these episodes "mute windows". Dropped texts are never backfilled — they are permanently absent from the .jsonl (verified by grepping unique phrases across the whole projects directory). Outside mute windows, mid-turn texts persist normally and promptly.
Evidence (from line-by-line jsonl inventories)
- Affected session (2.1.212): a 7-message stretch (13:49–13:56 UTC) where every message's
thinkingandtool_useentries were appended in real time, but zerotextentries were written — despite each message visibly containing text in the UI. The only persisted texts were the message before the window and the turn-final message after new operator input arrived. - Same session had a second mute window ~30 minutes later within the same conversation.
- A second session (2.1.211) shows two ~50-minute stretches of active work (39 and 36 consecutive assistant entries) with no text entries at all, plus a ~1-minute micro-window that swallowed 2 consecutive messages' texts while neighboring texts persisted.
- Parallel healthy sessions on the same host, same CC version, same model, same minutes persisted mid-turn texts normally (127/150, 35/52, 9/14 texts share a message id with a tool_use entry, i.e. mid-turn) → per-session defect, not host-wide.
- Rotation ruled out:
transcript_pathin hook stdin unchanged; no second file contains the session's texts. - Compaction ruled out: reproduced with no compaction event in the session.
Impact
- Permanent loss of conversation history — dropped assistant messages are unrecoverable (affects
--resume, auditability). - PreToolUse hooks that read the transcript deadlock. We run a policy hook that requires a marker in recent assistant texts. During a mute window the model can emit the marker forever — it never reaches disk, so the hook keeps blocking every Edit/Write/Bash until the turn ends (turn-final text appears to flush reliably). Multiple sessions were stuck this way for many minutes each, repeatedly, on the same day.
- Related observation while debugging (separate but adjacent): inside subagents, PreToolUse receives the parent session's
transcript_path, so a parent's stuck state transitively blocks all its subagents.
Workaround we use
Emit the required marker as the final text of the message, make no tool call after it, end the turn; after any new user input, the turn-final text is flushed and the next tool call passes. Verified repeatedly.
Repro notes
Episodic — we could not find a deterministic trigger (not compaction, not model, not version alone, not message content: within a mute window all texts are dropped regardless of content). Onset observed mid-turn during long multi-tool turns. If useful we can share sanitized jsonl inventories (entry type / content-block types / timestamps per line).
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗