[Bug] Background (daemon) sessions drop assistant text blocks from transcript when response mixes text with tool_use (regression 2.1.160 → 2.1.161)
Environment
- Claude Code: 2.1.161 (npm install, Linux)
- OS: Ubuntu 24.04 (kernel 6.17)
- Session type: background job, daemon backend (
"backend": "daemon",sessionKind: "bg"in the transcript records) - Model: claude-opus-4-8
Summary
In background (daemon) sessions, assistant text blocks are not persisted to the session transcript (~/.claude/projects/<project>/<session>.jsonl) whenever the response also contains tool_use blocks and two thinking blocks (interleaved thinking). The transcript ends up with only thinking records (empty thinking: "", signature present) plus the tool_use records — the text record between them is missing entirely.
This is a regression from 2.1.160: the same session has turns from the previous day on 2.1.160 where every text block was persisted correctly. After the daemon updated to 2.1.161 and the job restarted, only the very first response of the run (which had a single thinking block) kept its text; every subsequent response lost its text block.
Observed transcript pattern (sanitized)
# first response after restart — text persisted (single thinking block)
record 93 assistant thinking (thinking:"", signature present) req_A
record 94 assistant text[107 chars] req_A
record 95 assistant tool_use: ToolSearch req_A
# every later response — text block missing
record 99 assistant thinking (thinking:"", signature present) req_B
record 100 assistant thinking (thinking:"", signature present) req_B
record 101 assistant tool_use: Agent req_B
record 102 assistant tool_use: Agent req_B
# the response's text block was streamed live but never written
record 123 assistant thinking (thinking:"", signature present) req_C
record 124 assistant thinking (thinking:"", signature present) req_C
record 125 assistant tool_use: AskUserQuestion req_C
# a ~150-word answer preceding AskUserQuestion is absent from the jsonl
Scanning the whole file: after the restart on 2.1.161 there are zero assistant text records other than the first response, across ~10 consecutive responses that all contained user-facing text. Text-only final responses (no tool_use) DO persist fine.
Impact
- The background job viewer replays the conversation from the jsonl, so the user sees only tool-call summaries and a bare AskUserQuestion dialog with none of the assistant's prose (including the main deliverable the job was asked to produce).
- The job state extractor / timeline gets
text: ""for the turn, so the job list shows a stale state and detail (timeline.jsonlentry recorded with empty text). - The lost text is unrecoverable from disk — it only exists in the daemon's memory until the session produces a final text-only response.
Steps to reproduce
- Install Claude Code 2.1.161 on Linux, daemon backend.
- Start a background job that runs multiple turns mixing assistant prose with tool calls (extended/interleaved thinking active, so responses contain 2 thinking blocks).
- Inspect
~/.claude/projects/<project>/<session>.jsonl: responses withthinking ×2 + tool_usehave notextrecord; reopening the job in the viewer shows no assistant prose.
Expected behavior
Assistant text blocks are persisted to the transcript for every response, as in 2.1.160. (Thinking blocks being persisted with empty content + signature looks intentional; the regression is specifically the dropped text blocks.)
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗