Mid-turn assistant text persisted as empty thinking blocks (narration) — text lost from transcript JSONL (2.1.170)
Resolved 💬 2 comments Opened Jun 10, 2026 by acighi Closed Jun 14, 2026
Summary
On Claude Code 2.1.170 with claude-fable-5, short assistant text messages emitted between tool calls (mid-turn status updates / "narration") are rendered in the UI but persisted to the session transcript JSONL as empty thinking-type blocks — the text content is lost. Longer substantive texts and turn-final messages persist normally as type:"text" blocks.
Environment
- Claude Code 2.1.170 (CLI, macOS Darwin 25.4.0)
- Model: claude-fable-5
- Transcript:
~/.claude/projects/<project>/<session>.jsonl
What we observed
A mid-turn assistant message (shown on screen) is stored as:
{"type":"assistant","message":{"content":[{"type":"thinking","thinking":"","signature":"CAIS8AIKYwgOGAIqQOtX...QgluYXJyYXRpb24..."}]},...}
thinkingcontent is the empty string; the rendered text appears nowhere in the record.- The base64 signature metadata contains the string
narration(vsthinkingfor genuine thinking blocks), suggesting these are a distinct "narration" output channel serialized down the thinking path. - In one 3-hour session, 5 of 7 short mid-turn messages were lost this way; the 2 that persisted as
type:"text"were longer, substantive messages. Turn-final messages always persisted.
Why it matters
- Hooks that read the transcript can't see those messages. PreToolUse/Stop hooks that grep assistant text for required markers false-fire: we measured 865 blocks from two marker-checking hooks in one week, a large share caused by markers posted in chat but never persisted. (Local workaround: carry markers in a tool call's
descriptionfield, which always persists.) - Session logs are lossy as a record. Post-hoc session analysis, handoff generation, and compliance-style review lose all mid-turn assistant commentary.
Expected
Mid-turn assistant text should persist in the transcript with its content (as type:"text", or as a narration block carrying the text), matching what the user saw on screen.
Repro sketch
- CC 2.1.170, claude-fable-5, any project with a PreToolUse hook that greps the transcript for a marker string.
- Ask for a multi-step task; have the assistant emit a short one-line status message between two tool calls.
grepthe session JSONL for that line: absent; the corresponding record is an emptythinkingblock whose signature metadata decodes tonarration.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗