Session resume does not display assistant messages completed while user was absent
Summary
When a user leaves a Claude Code interactive session while the assistant is streaming a response (session lobby, terminal reload, CTRL+C), and then re-enters the session, the completed assistant response is NOT displayed. The session lobby correctly shows "unread message," but entering the session renders nothing. The JSONL session log on disk contains the complete response data.
Impact: Users lose visibility of completed work, leading to duplicate requests, missed instructions, and wasted API budget.
Reproduction Steps
- Start a Claude Code session:
claude - Send a prompt that takes several seconds:
Write a detailed 500-word essay about distributed systems. - While streaming, press
/to open the session lobby (or CTRL+C) - Wait 10-15 seconds for the response to finish in the background
- Re-enter the session from the lobby
- Observe: The assistant's response is missing
Scriptable reproduction
SESSION_ID=$(uuidgen)
timeout 3 claude --bare --print --output-format stream-json \
--include-partial-messages --session-id "$SESSION_ID" \
"Write a 500-word essay about distributed systems" > /tmp/partial.jsonl 2>&1
sleep 15
# JSONL has the complete response:
find ~/.claude/projects -name "${SESSION_ID}.jsonl" -exec wc -l {} \;
# Resume shows nothing:
claude --bare --print --output-format stream-json \
--resume "$SESSION_ID" "What did you just say?"
Expected Behavior
| Scenario | Expected | Actual |
|---|---|---|
| Leave during stream, return after completion | Full response displayed | Empty chat |
| Leave during stream, return during stream | Stream continues | Empty chat |
| Lobby shows "unread message" | Entering shows the message | Message invisible |
Evidence
We've confirmed this across 3+ sessions. In every case:
- The JSONL file contains the complete assistant response with intact
parentUuidchains - All
type: "text"content blocks have full text - The TUI does not replay these messages on re-entry
Root Cause Hypothesis
The session resume/hydration path reads the JSONL and reconstructs the conversation tree via parentUuid chains. Messages that were generated after the user disconnected may not be in the TUI's in-memory conversation state, and the hydration pass may not incorporate messages newer than the user's last-seen timestamp.
Environment
- Claude Code 2.1.98 (native binary, Arch Linux)
- Platform: Linux x86_64
- Terminal: kitty + tmux
Related Issues
- #44907 — SDK/print mode docs omit interrupted partial response persistence
- #40316 — Session becomes permanently unrecoverable after streaming errors
- #21617 — Conversation chain breaks mid-session
- #46603 — Resume shows stale messages: broken parentUuid chain
- #41230 — Messages sent to stdin during active turn are not persisted
Integration Tests
We've written 7 integration tests validating the expected contract (session JSONL completeness, resume display, interrupted stream recovery, multi-turn continuity, concurrent access, fork preservation). Available for reference if helpful.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗