/resume picker excludes sessions after moving them to a new project directory
Title
/resume picker excludes sessions after moving them to a new project directory, even when all on-disk references are updated
Environment
- Claude Code 2.1.139, macOS (Darwin 25.4.0, arm64)
- Bun-compiled native binary at
~/.local/share/claude/versions/2.1.139
Summary
After moving a project's session .jsonl files into a new ~/.claude/projects/<encoded-cwd>/ directory (because the working directory was reorganized on disk), the affected sessions:
- ✅ Appear in the Ctrl-A "all sessions" view in
/resume - ✅ Resume successfully via
claude --resume <session-uuid> - ❌ Are missing from the default project-scoped
/resumepicker for the new working directory
So the sessions are valid and indexed — only the current-project filter in the picker excludes them.
Repro
- Have an existing project directory, e.g.
/Users/me/old/pathwith sessions in~/.claude/projects/-Users-me-old-path/ - Move/rename the working directory on disk to a new location, e.g.
/Users/me/new/path - Move the session JSONLs into the new encoded directory:
~/.claude/projects/-Users-me-new-path/ - Update every path-keyed reference Claude Code stores:
- All
cwdfields inside each event line in the JSONLs (~thousands per file) - The
projectfield for every entry in~/.claude/history.jsonl
cd /Users/me/new/path && claude, then run/resume
Expected: the migrated sessions appear in the picker for the new project.
Actual: picker is empty for the new project. Ctrl-A still shows them. claude --resume <uuid> works.
What I audited and updated
~/.claude/projects/-Users-me-new-path/<uuid>.jsonl— file location ✓cwdfield on every event in each JSONL (~3,000 events total) ✓- Trailing events where the user
cd'd to home mid-session ✓ gitBranchfield already matched current branch ✓projectfield on 249 entries in~/.claude/history.jsonl✓~/.claude.jsonprojectsdict — the new path is present, the old path is not- File permissions normalized to
0600✓ - JSONL files still parse cleanly (verified via
json.loadsper line, zero malformed)
I also generated a sessions-index.json (since I noticed two such files in older project dirs), but strings on the binary returned zero matches for sessions-index / session-index / sessionIndex, so that file is unused by 2.1.x. (Those two existing index files are stale leftovers from January/February.)
Implications
There is some internal-to-Claude-Code mechanism that decides "this session belongs to project X" which is not any of:
- The encoded project-directory name where the JSONL lives
- The
cwdfield inside the events - The
projectfield in~/.claude/history.jsonl - A sidecar/index file on disk
Because all of those say "new path" and the picker still excludes the session.
Plausible candidates worth checking on the team's side:
- A per-session field captured at session creation time that isn't updated when content is rewritten externally
- A hash/fingerprint of the original cwd persisted somewhere
- A check on file inode, btime, or some other filesystem attribute that changes when files are moved
- An in-memory project→session map that's hydrated only from sessions created in-process during recent runs
Workaround
claude --resume <uuid> works fine — the sessions themselves are intact. Users who reorganize their on-disk project layout currently need to know their session UUIDs to recover access to the picker entry. A documented "session migration" path, or a claude --reassign-session <uuid> --to <project-path> command, would close the gap.
Why this matters
Restructuring local project locations is normal (consolidating worktrees, renaming directories, etc.). Today there is no documented way to keep /resume working after such a move, even though all the obvious on-disk state can be migrated by hand.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗