[BUG] Resuming sessions only works from the directory in which they were started
Status Open
Maintainer reply None cached
Workaround ✓ Mentioned in thread ↓
Activity 24 comments · opened Aug 14, 2025
Environment
- Platform (select one):
- [ ] Anthropic API
- [ ] AWS Bedrock
- [ ] Google Vertex AI
- [X] Other: Desktop
- Claude CLI version: 1.0.80 (Claude Code)
- Operating System: Debian Linux
- Terminal: VS Code terminal + bash
Bug Description
It is only possible to resume conversations from the same directory in which they are started.
Steps to Reproduce
Start a session with claude --session-id UUID
End that session and change to another directory
Try to resume the session with claude --resume UUID
Expected Behavior
Session should be resumed
Actual Behavior
Error: No conversation found with session ID: UUID
Additional Context
The problem seems to be that Claude is storing its conversations under /home/USER/.claude/projects/PROJECT_PATH/ where project path is a string built from the current working directory with the slashes removed.
24 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Some of the issues marked above are related but not duplicates. This issue focuses specifically on the
--session-id UUIDand--resume UUIDpair of arguments which should be independent of the current working directory. This does not apply to--continueto which probably should continue the last conversation that took place in the current working directory.A simple solution to this problem which would require very few changes would be to search all of
/home/USER/.claude/projects/for a conversation when the UUID is explicitly given.+1
+1. Our use case is in the sdk - we duplicate the root directory structure on every iteration to save history, but want to resume in the new directory
I just got bit by this one as well.
This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.
This is still an issue.
I can also confirm that this is still an issue. The same issue is _also_ present in the Claude Agent SDK v0.1.62.
Just hit another variant of this issue. When using the resume menu (claude --resume) with A to show all projects, selecting a session from a different directory generates the wrong cd command.
What happened:
Session was created in /home/artur/Repositories (confirmed in ~/.claude/history.jsonl):
{"project":"/home/artur/Repositories","sessionId":"XXX"}
But when resuming from /home/artur/Repositories/tinygrad, the menu showed:
This conversation is from a different directory.
To resume, run:
cd /home/artur/Repositories/tinygrad && claude --resume XXX
Running that command: No conversation found with session ID: XXX
The resume menu should read the project field from the history file instead of using pwd.
Environment: Claude Code v2.0.69, Linux
Just ran into this myself. Notably this is tagged "platform:linux" but it also shows up on windows, and I'd assume macos as well. Adding another use case that reinforces why this matters.
The launch directory determines Claude Code's security sandbox scope. If you start Claude from a parent directory, create a new project subdirectory during the session, and want to continue working with a tighter sandbox, you're stuck - you can't resume the session from the subdirectory.
This is particularly relevant when a session evolves from exploration/scaffolding (broad access needed) into focused development (narrower access preferred). Currently you have to choose between an overly permissive sandbox or losing your session context.
This also affects --resume <session-name> (not just UUIDs). After using /rename my-session, running claude --resume my-session from a different directory fails with "No conversations found to resume" - the name lookup is scoped to the current project directory's session store.
Manually copying the session .jsonl file and its corresponding directory from ~/.claude/projects/<old-path>/ to ~/.claude/projects/<new-path>/ does appear to work. The session loads and functions correctly from the new location. This suggests the fix could be straightforward - the session data itself isn't path-dependent, just the lookup mechanism.
@jeff-hiner yes, this also happens on macOS. I can confirm.
Additional reproduction case: /resume suggests the wrong directory
I encountered a variant of this bug where the /resume command actively provides an incorrect directory suggestion.
Environment:
Scenario:
/opt/repos/myproject"/opt/repos/myproject"~/.claude/projects/-home-user/<session-id>.jsonlThe bug:
When running /resume, Claude suggested:
cd /opt/repos/myproject && claude --resume <session-id>This fails because the session is stored under -home-user, not -opt-repos-myproject. The suggestion uses projectPath (where I worked) instead of the actual storage location (where I launched Claude).
Workaround: Resume from the original launch directory:
cd /home/user && claude --resume <session-id>+1
I was working deeply in one repository and Claude+VS Code session, but a part of the roadmap for the feature was to move it to another repo. When done I wanted claude to change its working directory, exit and then resume from the other folder in another VS Code session.
still a problem today, really weird this is not prioritised, it prevents Claude CLI from actually being the single source of truth across several applications (as they all come in with their own folder structure)
Seems like a no-brainer to me to allow somebody to search past sessions across all projects in order to figure out which one to resume.
I don't even care which working directory they resume in. I just want the ability to find that one random session that I start every week in the wrong place and pick up from where I left off.
Especially annoying/damaging when you start a new project from a different directory - the project directory obviously didn't exist when you started it - so you have to work your way backwards and figure out which random other product folder you started from in order to be able to actually resume that.
In theory, it's a skill issue; I should write these things down or dump enough context in order to be able to pick back up without being in the same conversation. But it just seems to kind of defeat the purpose of projects partially and feels like a pretty low hanging fruit patch to make.
There is a workaround:
ag -l "your_search_string_here" ~/.claude/projectswill at least point you to the right project.
Filed #60851 with same root cause (macOS, but mechanism is platform-agnostic — see also #48394 on Windows and #57920 on macOS worktree removal). Letting mine auto-close as dup; migrating the proposed fix here since this thread has the most traction.
Proposed fix (minimal)
Decouple session lookup from cwd path. One small-footprint option:
<git-root-or-cwd>/.claude/sessions(a plain newline-separated text file of UUIDs)./resumeand--continue, read that pointer file first; fall back to today's cwd-slug lookup if absent.--resume <id>, do a global scan of~/.claude/projects/**/<id>.jsonlso the UUID is a true global key.Properties:
.gitignore.~/.claude/.mv,git mv, worktree clones, symlinks.Alternative
Key the session directory by
git remote get-url originhash instead of cwd path, falling back to cwd slug for non-git dirs. Rename-proof for the common (git) case.Why
--resume <id>deserves special treatment--resume <session-id>reads like a global lookup by a content-addressable key (the UUID), but it's actually scoped by cwd. Users reasonably expect a UUID-keyed flag to work from anywhere — the global-scan fallback in step 3 above is the smallest change that delivers that expectation.Resumability keyed to the starting cwd is a trap. In MartinLoop we learned the hard way that
session identity != workspace path; workspace is one dimension of context, not the primary key. If resume only works from the original directory, users lose portability and auditability the moment they move a checkout, use a different worktree, or reopen from a sibling clone.A stronger model is stable session id -> canonical session receipt/manifest, with cwd/worktree captured as metadata and remapping warnings on resume when needed. That keeps the safety checks without making resume itself path-fragile.
Is there any progress on this?
Still hitting this, with an extra wrinkle worth flagging: it also happens when a session starts in the main repo and only switches into a worktree partway through. Once that switch happens the session gets re-indexed under the worktree's project path, so it silently drops out of
/resumein the main repo with no hint that it's now stored somewhere else.Ran into the same wall. The sessions aren't gone; they're filed under the project slug for whatever directory you started in, and
--resume UUIDonly looks under the slug built from your current directory. You already spotted the mechanism in the body:~/.claude/projects/<slug>/, where the slug is the cwd with the slashes swapped out. Start somewhere else and the resolver builds a different slug, looks there, and reports "No conversation found".The part the toolkit can't touch is the resolver itself. Making
--resume UUIDsearch every slug for the UUID (what you proposed) is an upstream change to the CLI, and nothing on the file layer can force it. What I can help with is finding the session in the meantime, because it's sitting intact under the original slug.I built
BasedGPT/claude-code-session-recoveryfor exactly this kind of "which slug is my session under" problem.diagnose.pywalks~/.claude/projects/and maps every slug against the transcript files inside it, so you can see which directory holds the UUID without guessing. Once you know the slug,cdback into the matching path and--resume UUIDresolves. dennislysenko'sag -l "<string>" ~/.claude/projectsone-liner further up the thread does the same job from the other direction, when you remember the content but not the path.To confirm before relying on it, open
~/.claude/projects/and check that a directory matching your original cwd exists with a<UUID>.jsonlinside. That file is your conversation history, untouched.Hope this helps, if my tools are able to help you, would appreciate a ⭐ :)
There's a new built-in
/cdcommand now, I've been using it for weeks to successfully move existing sessions to different directories.Posting this here as issue 52494 was closed. The migration was successful-ish (but mostly not as ran into this bug in various ways).
Cowork sessions orphaned after machine migration with a Windows username change — full field report, root causes, and working repair scripts
Environment
Claude_pzs8sxrjxfjjc)EmmaBack, new:EmmaO'Farrell— note the apostrophe, which becomes a dash in slugs)Summary of symptoms (in the order encountered)
local-agent-mode-sessionsto the new machine, every session failed withNo conversation found with session ID: <uuid>— despite files present on disk and the same account signed in. The knowledge base resolved correctly....EmmaBack...and...EmmaO-Farrell...) with conversation content split between them..jsonlin the project folder and the app's pointer moves to it — so the session's displayed history "vanishes" the moment the user types, while the old transcript remains on disk. Users will interpret this as data loss.Root cause
Conversations are stored under a path-derived slug:
The slug encodes the absolute path of the session's outputs directory. On resume, the app recomputes the slug from the current path. A username/path change means the recomputed slug no longer matches the stored folder → lookup fails → app reports "No conversation found," and on interaction it creates a fresh conversation instead of continuing the old one.
Special characters are flattened:
EmmaO'Farrell→EmmaO-Farrellin slugs (apostrophe → dash). Repair scripts must use the dash form for folder names but the literal form for paths inside JSON.Compounding problems
\\?\extended-length prefix.Working repair (restored 20 of 21 sessions; last one via the workaround below)
Preconditions: Cowork fully quit, OneDrive sync paused, old machine signed out and off, full backup of
local-agent-mode-sessionstaken first.1) Inventory first (read-only) — do not blind-rename. Sessions can have OLD-only, NEW-only, or twin folders; twins may both contain real conversations. List every
.claude\projectsslug folder with file counts, then handle:2) Bulk rename + in-file path fix (
\\?\prefix throughout; noteGetDirectories("\\?\...")returns already-prefixed paths — do not prefix them again, or calls fail with "syntax is incorrect"):Notes from the field:
Directory.Move= a stale handle (app, Explorer window inside the folder, OneDrive, indexer). Quit everything / pause OneDrive; a reboot-then-immediately-run clears it reliably.Residual bug even after correct repair — pointer moves on interaction
For one session (twin folders, multiple conversation files in one slug folder), even with files parseable, correctly named, and correctly located: the session displays no history, and typing into any migrated session creates a new empty
.jsonland switches the app to it. This spread — each migrated session interacted with lost its displayed history the same way.Practical workaround (works): accept the new conversation, attach the old
<session-id>.jsonltranscript to it, and prompt:Rehydrated sessions are clean-born on the new machine and need no further repair. This is viable but manual, per session, and loses in-app scrollback of the original thread.
Suggested fixes
\\?\or long-path opt-in) so slug folders don't exceed MAX_PATH and become unrepairable by users.Related