[BUG] Background session that entered a worktree resumes blank (empty history, same session ID) after cold reopen

Open 💬 0 comments Opened Jul 9, 2026 by georgysavva

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 ID d2b59430-9475-47fe-aa83-0066ee381883
  • ~19:40 — session runs EnterWorktree into an existing worktree under ~/repo/.claude/worktrees/<name> (worktree-state marker has enteredExisting: true); transcript relocates to ~/.claude/projects/<munged-repo>--claude-worktrees-<name>/d2b59430-….jsonl, with relocated markers pointing at the worktree cwd
  • 19:40–20:58 — work proceeds; multiple warm respawns re-stamp metadata into the relocated file (13 relocated markers accumulate) — warm resumes follow the relocation fine
  • 20:58:51 — transcript ends abruptly on an assistant tool_use with no tool_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-….jsonl is 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:

  1. the respawn follows the relocation (or searches project dirs by session ID) and resumes the relocated transcript; or
  2. the job's registered cwd is updated when the session enters/exits a worktree, keeping registration and transcript location in sync; or
  3. 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

  1. Start a background agent (daemon backend) with cwd = a git repo's main checkout.
  2. Have it EnterWorktree (create or enter a worktree under .claude/worktrees/). Verify the session .jsonl moved to the worktree-keyed dir under ~/.claude/projects/.
  3. Kill the session process mid-turn and let the daemon go cold (workspace restart or daemon stop).
  4. Reopen the agent from the agents view.
  5. The session resumes blank; the same session ID now has a second, fresh .jsonl under 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 /cd reappearing 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

View original on GitHub ↗