# Resume Claude Session

> Recover a Claude Code session that fails to resume with "No conversation found" — finds the session file across all encoded project directories, extracts the real cwd from inside the jsonl, and reruns the corrected `claude --resume` command. Trigger when the user pastes a failing `cd … && claude --resume <id>` block, asks to "resume that session", "open the lost session", or any variant of recovering a Claude session that errored on resume. Also trigger if the user asks how to install or set up this skill.

- Skill: `travcjohnson/resume-claude-session` (Agent Skill)
- Install (CLI): `npx skillmds@latest add travcjohnson/resume-claude-session`
- Raw SKILL.md: https://api.skillmd.com/api/skills/travcjohnson/resume-claude-session/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: travcjohnson (https://skillmd.com/u/travcjohnson)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/travcjohnson/resume-claude-session

---


# Resume a Lost Claude Code Session

## One-time setup (if the user is installing this skill)

If the user was given this file and asks to set it up, do it for them:

```bash
mkdir -p ~/.claude/skills/resume-claude-session
# copy or write this SKILL.md into that folder
```

That's it — Claude Code auto-discovers skills in `~/.claude/skills/<name>/SKILL.md`. Tell them to start a new session and say "resume my lost session" (or paste the failing command) to trigger it. No dependencies beyond `claude` itself and standard Unix tools (`find`, `grep`, `cut`).

## When this fires

The user pastes (or describes) a failing resume attempt like:

```
cd '/path/to/dir' && claude --resume '<uuid>'
No conversation found with session ID: <uuid>
```

The cause is almost always that the `cd` path doesn't match the cwd where the session was originally created — `claude --resume` is scoped to `~/.claude/projects/<encoded-cwd>/`, not searched globally.

## The fix

1. **Extract the session ID** from the pasted command (UUID after `--resume`). If the user doesn't have an ID, list candidates: the most recently modified `*.jsonl` files under `~/.claude/projects/` are the most recent sessions:

   ```bash
   find ~/.claude/projects -maxdepth 2 -name "*.jsonl" -not -path "*/subagents/*" -newer /tmp -print 2>/dev/null
   ls -t ~/.claude/projects/*/*.jsonl 2>/dev/null | head -10
   ```

2. **Locate the actual session file.** Search ALL project dirs, not just the one implied by the failed command:

   ```bash
   SESSION_FILE=$(find ~/.claude/projects -maxdepth 2 -name "<id>.jsonl" -not -path "*/subagents/*" -print -quit)
   ```

   - If empty → session truly doesn't exist (never persisted, deleted, or wrong ID). Report this and offer `claude --continue` (resumes the most recent session in the current directory) instead. Stop.

3. **Extract the real cwd** from the jsonl. The directory name is lossy (`/` and `_` both encode to `-`), so don't try to decode it — read the canonical field from inside the file:

   ```bash
   REAL_CWD=$(grep -m1 -o '"cwd":"[^"]*"' "$SESSION_FILE" | cut -d'"' -f4)
   ```

   If `REAL_CWD` is empty (very old session formats), fall back to attempting to decode the directory name and ask the user to confirm before proceeding.

4. **Preserve any flags** from the original command (e.g. `--dangerously-skip-permissions`). Include a flag only if the original command had it.

5. **Hand back the corrected command** for the user to run in their terminal:

   ```bash
   cd '<REAL_CWD>' && claude --resume '<id>'
   ```

   You cannot run this for them — `claude` is interactive and would nest inside the current session. Print it clearly and tell them to paste it into a NEW terminal tab/window/pane. If their terminal multiplexer has a CLI you can drive (tmux, cmux, etc.), offer to open the pane and send the command — e.g. for tmux:

   ```bash
   tmux split-window -h "cd '<REAL_CWD>' && claude --resume '<id>'"
   ```

6. **Report back** to the user with:
   - The corrected cwd (so they understand what changed)
   - A one-line summary: "Original tried `<wrong-cwd>`, real cwd is `<right-cwd>` — run the command above in a new terminal."

## Edge cases

- **Multiple matches** (shouldn't happen with UUIDs, but possible if a subagent file leaked into a non-subagents path): pick the largest file (most likely the real session, not a stub).
- **Worktree branch already checked out elsewhere** by another claude instance: the resume will still work — claude doesn't care about git state, only the cwd-scoped jsonl. But warn the user if they're about to operate concurrently on the same worktree.
- **The cwd no longer exists** (deleted worktree or temp dir): `cd` will fail. Recreate the directory (`mkdir -p`) or advise the user the session's working directory is gone; resuming from a recreated empty dir still restores the conversation, just not the files.

## Why the lookup fails in the first place

`~/.claude/projects/` has one subdirectory per *cwd that ever ran claude*. A git worktree at `<repo>/.claude/worktrees/<branch>` is a different cwd from the main repo root, so they get separate session dirs. Whatever generated the failed resume command (often another tool that captured the session ID without capturing the cwd) paired the right ID with the wrong path.

## Diagnostic rule for future cases

When `claude --resume <id>` says "No conversation found":

```bash
find ~/.claude -name "<id>*" 2>/dev/null
```

- Returns a path under `~/.claude/projects/<encoded-cwd>/` → session exists, wrong cwd. Use this skill.
- Returns nothing → session was never written or was deleted. Offer `--continue` instead.

Never accept "not found" from a path-scoped CLI as ground truth. Verify with the filesystem.

