Why can't Claude Code find my session?
claude --resume <session-id> Searches this project and its worktrees, then every other project on the machine (v2.1.223 and later).
Answer
No conversation found with session ID means no stored transcript matched, and the usual reasons are not corruption. Sessions from claude -p and the SDK stay out of the picker and of --continue but resume by ID; a session moved with /cd lives in the other directory's storage; the cross-project search resolves an ID only when exactly one other project holds it; and transcripts older than 30 days are deleted. Widen the picker with Ctrl+A and look on disk before assuming the session is gone.
What it does
A session goes missing in five documented ways. Start with the one that matches what you saw.
No conversation found with session ID
The message --resume prints when no stored transcript matches the ID. Two things it is not. It is not the picker's scope: an ID search covers the current project and its git worktrees first, then every other project on the machine, from v2.1.223 on. Before that it stopped at the current project and its worktrees, so on an older version the same ID works only from the directory that owns it. And it is not a permissions problem.
What it is: either no transcript with that ID and any messages in it exists, or more than one other project holds a copy. A hand-copied duplicate makes the cross-project search report not found rather than resume an arbitrary copy.
The session is not in the picker
The picker shows sessions from the current worktree, plus sessions started elsewhere that added this directory with /add-dir. Three kinds never appear:
- sessions created with
claude -por the Agent SDK, which resume by ID only - sessions whose first prompt was
/loop; before v2.1.211, a/looprun anywhere early in a conversation hid the session permanently - sessions moved with
/cd, which live in the new directory's storage from v2.1.169 on
Ctrl+W widens the list to every worktree of the repository, Ctrl+A to every project on the machine.
--continue opened a different session
"Most recent" skips -p and SDK runs, background sessions and sessions that began with /loop, so the newest interactive session wins even when a script ran later. claude -p --continue includes -p, SDK and /loop sessions and still skips background ones.
The default display name is not a handle
A label like my-app-3f, the working directory plus two characters, identifies a running session in listings, and passing it to --resume finds nothing. A name you set, the generated title, or the ID are the handles; resuming a specific session covers them.
It is past the retention window
Transcripts are kept 30 days by default. Claude Code deletes older ones in a background sweep after a session starts, so a session you last touched five weeks ago is gone, not hidden. cleanupPeriodDays changes the window for the future, not for what was already removed.
How to check
Widen the picker first. Ctrl+A shows every project; a session that appears there but not in the default list was started elsewhere or moved with /cd.
Then look on disk. Transcripts are JSONL files at ~/.claude/projects/<project>/<session-id>.jsonl, where <project> is the working directory path with every non-alphanumeric character replaced by -. CLAUDE_CONFIG_DIR, if set, moves the whole tree:
ls ~/.claude/projects/*/<session-id>.jsonl
One match: --resume <session-id> from anywhere finds it on v2.1.223 or later, and from that directory on any version. Two matches: a duplicate, which is why the lookup refuses. No match: the transcript was deleted, or was never written, which happens in a -p run with --no-session-persistence or under CLAUDE_CODE_SKIP_PROMPT_HISTORY.
Check the version when the ID form fails from another directory:
claude --versionHow to fix it
It belongs to another directory. Run --resume <session-id> from anywhere on v2.1.223 or later, or cd there first. From the picker, selecting a session from an unrelated project copies a cd and resume command to your clipboard rather than opening it; if that directory no longer exists, Claude Code resumes the session where you are instead.
Two projects hold a copy. Delete the copy you do not want and leave one.
It is hidden from the picker. Resume by ID. For a -p run, the ID is in the JSON result of --output-format json; otherwise it is the transcript's filename.
--continue picked the wrong one. Use --resume and choose, or pass the ID.
It expired. There is nothing to resume. Widen the window before it happens again:
{
"cleanupPeriodDays": 90
}Example
Find the transcript, then resume it:
ls ~/.claude/projects/*/7f3d9a2c-1b4e-4c8a-9f2d-3e5b7c1a0d6f.jsonl
claude --resume 7f3d9a2c-1b4e-4c8a-9f2d-3e5b7c1a0d6f
Ask a session that never appears in the picker a question anyway:
claude -p --resume <session-id> --output-format json "summarise what we changed"Common mistakes
Reading not-found as deleted. Check the disk. A transcript in another project's directory is the most common outcome, and it resumes fine.
Copying transcripts between projects by hand. The duplicate is exactly what makes the cross-project lookup refuse to guess.
Expecting a -p session in the picker. It is kept out by design. Keep the ID from the run's JSON output if you will want the session back.
Parsing the JSONL yourself. The entry format is internal and changes between versions. /export and claude -p --resume are the stable interfaces.