[BUG] Background session that entered a worktree resumes blank (empty history, same session ID) after cold reopen
Environment
- Claude Code v2.1.204, background agent (daemon backend), reopened via the agents view
- Linux x86_64 (remote dev workspace)
- Transcript-follows-cwd relocation active (present since ~v2.1.201; sessions on v2.1.198 and earlier did not relocate)
Summary
A background (daemon) session used EnterWorktree mid-session, and its transcript was relocated to the worktree-keyed project directory under ~/.claude/projects/ (expected — transcripts follow the session's cwd). The session process later died mid-turn. On the next cold reopen, the respawn resolved the session from the job's registered cwd (the main checkout's project dir), did not follow the relocation, and silently started a brand-new empty conversation reusing the same session ID. The result: two .jsonl files with the same session ID in different project dirs, and the user sees a long-running task's entire history vanish with no error.
v2.1.202 fixed the loud version of this — "Fixed background agent sessions that entered a git worktree crash-looping with 'No conversation found' when reopened" — but on v2.1.204 the same lookup failure appears to survive in a silent form, which is arguably worse: it looks like total data loss and invites the user to redo the work.
Observed timeline (2026-07-08, UTC)
- 19:06 — bg job created from the agents view; registered cwd = main checkout (
~/repo); session IDd2b59430-9475-47fe-aa83-0066ee381883 - ~19:40 — session runs
EnterWorktreeinto an existing worktree under~/repo/.claude/worktrees/<name>(worktree-statemarker hasenteredExisting: true); transcript relocates to~/.claude/projects/<munged-repo>--claude-worktrees-<name>/d2b59430-….jsonl, withrelocatedmarkers pointing at the worktree cwd - 19:40–20:58 — work proceeds; multiple warm respawns re-stamp metadata into the relocated file (13
relocatedmarkers accumulate) — warm resumes follow the relocation fine - 20:58:51 — transcript ends abruptly on an assistant
tool_usewith notool_result: the process died mid-turn - 23:40 — cold reopen from the agents view. The respawn (flags from
~/.claude/jobs/<id>/state.json) comes up with empty history; a new~/.claude/projects/<munged-repo>/d2b59430-….jsonlis created containing only fresh metadata (ai-title,agent-name,mode,permission-mode,file-history-snapshot) and the new user turn. No error is surfaced. - Job-level metadata (job name, task list) survives — it lives in
~/.claude/jobs/<id>/state.json— which makes the session look even more like itself-with-amnesia rather than a fresh session.
Expected
Any of:
- the respawn follows the relocation (or searches project dirs by session ID) and resumes the relocated transcript; or
- the job's registered cwd is updated when the session enters/exits a worktree, keeping registration and transcript location in sync; or
- at minimum, the reopen fails loudly ("conversation not found at expected location") instead of silently minting an empty conversation under the same session ID.
Repro sketch
- Start a background agent (daemon backend) with cwd = a git repo's main checkout.
- Have it
EnterWorktree(create or enter a worktree under.claude/worktrees/). Verify the session.jsonlmoved to the worktree-keyed dir under~/.claude/projects/. - Kill the session process mid-turn and let the daemon go cold (workspace restart or daemon stop).
- Reopen the agent from the agents view.
- The session resumes blank; the same session ID now has a second, fresh
.jsonlunder the launch-dir project.
Notes
- The original transcript is intact on disk the whole time — this is a resume-path lookup bug, not data loss. Recovery requires knowing to look in the worktree-keyed project dir.
- Likely the same family as v2.1.196's "Fixed sessions moved with
/cdreappearing in the old directory's resume list after a non-graceful exit" and v2.1.202's worktree crash-loop fix quoted above.
🤖 Generated with Claude Code