claude-code - 💡(How to fix) Fix Sessions become unresumable after EnterWorktree → ExitWorktree, missing from both same-cwd and cross-worktree /resume pickers

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

A long-running Claude Code session that used EnterWorktree to enter a worktree, then exited (via /exit or end-of-turn) without the harness fully clearing the worktree binding, becomes invisible in /resume — both in the default same-cwd picker and in the cross-worktree "show other worktrees" picker. The only way to recover the session is to know the session UUID and pass it to claude --resume <uuid> directly.

Reproduction was observed on Windows. The session held active work that the user could not get back to via the normal resume UI.

Root Cause

I inspected the session jsonl at:

~/.claude/projects/<project-slug>/<sid>.jsonl

Findings:

  • Session lifecycle: ~7 days old, last activity earlier today. 5,320 entries, 11 MB, 287 worktree-state events (heavy EnterWorktree usage throughout).
  • First cwd: the project root → so the session is indexed under the project root slug, not under any worktree-specific slug.
  • cwd distribution within the session (top entries):
    • <HOME>\project\<PROJECT>\.claude\worktrees\<WT_A> — 838 entries
    • <HOME>\project\<PROJECT> — 672 entries
    • <HOME>\project\<PROJECT>\.claude\worktrees\<WT_B> — 371 entries
    • …(~17 more cwds, mostly worktrees)
  • Last worktree-state events (in order):
    // line 5304
    { "worktreePath": "...\\<WT_A>", "enteredExisting": true, ... }
    // line 5310
    null
    // line 5314
    null
    So the harness did emit two trailing null worktree-state events, presumably from ExitWorktree. But the session still does not appear in either /resume view from the project root.
  • Last user-issued command before unresumability: /resume (which itself printed This conversation is from a different directory. To resume, run: cd '<root>' && claude --resume <other-sid> for a different session — i.e. the picker thought the current session belonged to a different directory than where the user actually was), then /exit, whose local-command-stdout was:
    Returned to <HOME>\project\<PROJECT> (worktree at <HOME>\project\<PROJECT>\.claude\worktrees\<WT_A> left in place)

Fix Action

Workaround

Pass the session UUID directly: claude --resume <uuid>. The UUID can be recovered by listing ~/.claude/projects/<project-slug>/*.jsonl by modification time.

Code Example

~/.claude/projects/<project-slug>/<sid>.jsonl

---

// line 5304
  { "worktreePath": "...\\<WT_A>", "enteredExisting": true, ... }
  // line 5310
  null
  // line 5314
  null

---

Returned to <HOME>\project\<PROJECT> (worktree at <HOME>\project\<PROJECT>\.claude\worktrees\<WT_A> left in place)
RAW_BUFFERClick to expand / collapse

Bug: Sessions become unresumable after EnterWorktree → ExitWorktree → end, in both same-cwd and cross-worktree /resume pickers

Summary

A long-running Claude Code session that used EnterWorktree to enter a worktree, then exited (via /exit or end-of-turn) without the harness fully clearing the worktree binding, becomes invisible in /resume — both in the default same-cwd picker and in the cross-worktree "show other worktrees" picker. The only way to recover the session is to know the session UUID and pass it to claude --resume <uuid> directly.

Reproduction was observed on Windows. The session held active work that the user could not get back to via the normal resume UI.

Environment

  • OS: Windows 10 Pro 10.0.19045
  • Shell: PowerShell + Git Bash
  • Claude Code: Opus 4.7 (1M context), claude-opus-4-7[1m]
  • Multiple concurrent Claude Code processes running against the same project, in different terminals/worktrees

(Paths in this report are redacted as <HOME>, <PROJECT>, <WT_A>, <WT_B>, etc.)

Symptoms

  1. User runs /resume from the original project cwd (<HOME>\project\<PROJECT>).
  2. The picker shows some sessions but omits the specific session the user actually wants to resume (a session that was last active <1h ago, in the same project).
  3. User tries the cross-worktree resume option ("show sessions from other worktrees"). The missing session is still not listed.
  4. Direct invocation works: claude --resume <full-uuid> recovers the session cleanly.

Root cause analysis

I inspected the session jsonl at:

~/.claude/projects/<project-slug>/<sid>.jsonl

Findings:

  • Session lifecycle: ~7 days old, last activity earlier today. 5,320 entries, 11 MB, 287 worktree-state events (heavy EnterWorktree usage throughout).
  • First cwd: the project root → so the session is indexed under the project root slug, not under any worktree-specific slug.
  • cwd distribution within the session (top entries):
    • <HOME>\project\<PROJECT>\.claude\worktrees\<WT_A> — 838 entries
    • <HOME>\project\<PROJECT> — 672 entries
    • <HOME>\project\<PROJECT>\.claude\worktrees\<WT_B> — 371 entries
    • …(~17 more cwds, mostly worktrees)
  • Last worktree-state events (in order):
    // line 5304
    { "worktreePath": "...\\<WT_A>", "enteredExisting": true, ... }
    // line 5310
    null
    // line 5314
    null
    So the harness did emit two trailing null worktree-state events, presumably from ExitWorktree. But the session still does not appear in either /resume view from the project root.
  • Last user-issued command before unresumability: /resume (which itself printed This conversation is from a different directory. To resume, run: cd '<root>' && claude --resume <other-sid> for a different session — i.e. the picker thought the current session belonged to a different directory than where the user actually was), then /exit, whose local-command-stdout was:
    Returned to <HOME>\project\<PROJECT> (worktree at <HOME>\project\<PROJECT>\.claude\worktrees\<WT_A> left in place)

Hypothesis

The resume picker appears to filter candidates using a combination of:

  1. The session's index folder (= the slug derived from the first cwd).
  2. The latest worktree-state value in the session's jsonl.
  3. Possibly the current cwd of the invoking claude process.

When the latest worktree-state does not cleanly match the invoking cwd (or has a non-null worktree binding that is stale because the harness didn't roll it back, or has null-but-with-a-prior-non-null-active-worktree that the picker treats as "still in a worktree"), the session is dropped from both pickers:

  • Same-cwd picker: rejects because "session belongs to a different directory".
  • Cross-worktree picker: rejects because the worktree state doesn't match any known worktree (maybe the worktree was already removed at the OS level, but worktree-state still references it).

This is consistent with the "worktree at … left in place" line — the harness left the worktree on disk but the session metadata is in an in-between state.

Steps to reproduce (best guess)

  1. Start a long-running Claude Code session in the project root.
  2. Use EnterWorktree (or cd into an existing worktree) multiple times across the session, hopping between worktrees.
  3. In one of the worktrees, use a sub-agent that itself enters/exits the worktree (sidechain).
  4. Toward the end, run /resume (which lists other sessions, not the current one), then /exit.
  5. Open a new claude from the project root → run /resume. The just-ended session is missing.
  6. Toggle the cross-worktree picker option. Still missing.
  7. claude --resume <known-uuid> works.

I have not yet constructed a minimal repro outside this real session; happy to try if you point me at what state to inspect.

Workaround

Pass the session UUID directly: claude --resume <uuid>. The UUID can be recovered by listing ~/.claude/projects/<project-slug>/*.jsonl by modification time.

Suggested fix directions

  • The resume picker should fall back to any session whose index folder matches the project root, regardless of trailing worktree-state, when the user explicitly toggles "show all sessions for this project".
  • Or: when worktree-state is null at the tail of the file, treat the session as belonging to its index-folder cwd, not to the last non-null worktree-state.
  • Or: list the session under both the project root and any worktree it touched during its lifetime, so the cross-worktree picker can find it.

Privacy note

Paths, project names, and worktree names have been redacted. I can share a redacted excerpt of the offending jsonl on request.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING