You close your laptop. Next morning, claude --continue (or claude --resume) reopens the session. It looks like the same conversation — the tool-call history is visible, the plan is there. But the moment you say “continue”, Claude asks what project this is, re-reads files it already read yesterday, and re-proposes a design you explicitly rejected at 5pm. Resume gives you the appearance of continuity without the substance.
Fastest fix (90 seconds): before you type “continue”, paste a short “current state” message that states the project, the decisions already made, the files in scope, and the next concrete step. Re-priming the live context beats fighting the resume mechanism every time. The rest of this guide explains why memory vanishes and how to make state survive a close-and-reopen reliably.
Under the hood: what always survives a resume is the visible transcript stored on disk. What does not reliably survive is the model’s working context — the implicit summaries, the full tool-result bytes, the inferred decisions. Those get reconstructed from the transcript on reopen, and the reconstruction is lossy.
Which bucket are you in?
| Symptom on resume | Most likely cause | Jump to |
|---|---|---|
History shows Compacted / summarized turns; specific decisions missing | Auto-compaction dropped the detail | Cause 1 |
| Claude immediately re-reads files it read yesterday | Tool results not rehydrated | Cause 2 |
| Only the last few messages load; older history unreachable | Broken parentUuid chain in the .jsonl | Cause 3 |
| Resume hangs or never finishes loading | Oversized tool-result lines in the session file | Cause 3 |
| Behavior changed (different test cmd, package manager) | CLAUDE.md / settings edited between sessions | Cause 4 |
| ”File not found” for paths that worked yesterday | Resumed from a different working directory | Cause 5 |
| A deep subagent finding is now one sentence | Subagent/Task result was ephemeral, then compacted | Cause 6 |
--resume <id> says “No conversation found” | Wrong cwd, or file aged out after 30 days | Cause 7 |
Common causes
Ordered by impact.
1. Auto-compaction discarded the working context
Long sessions get compacted. As of June 2026, auto-compaction triggers when token usage reaches roughly 98% of the effective context window: Claude Code first clears older tool outputs, then summarizes the older conversation into a condensed history and starts a fresh context from that summary. Nuance is lost — “we decided not to use Redis” can collapse into a one-line note, or drop out entirely.
How to spot it: Run /context mid-session to see what is consuming space; a session that auto-compacted shows a summary block at the top of the transcript instead of the original turns. Decisions you remember making are not in the visible history.
2. Resume rehydrates the message text, not the full tool-result bytes
Tool result blocks (file contents, command output) are the bulkiest part of a transcript. On reopen, Claude knows from the text that it “read foo.ts”, but the live context does not necessarily hold foo.ts’s bytes again — large outputs may be stored out of line and not reloaded into working memory.
How to spot it: Claude immediately re-reads the same files it read yesterday. Token/cache counters reset despite the visible transcript still showing the old reads.
3. The .jsonl transcript chain is broken or oversized
Sessions are stored as JSONL where each line links to its parent via parentUuid. Resume walks that chain backward from the last message. If the chain breaks (a known class of bug where a file-history-snapshot messageId collides with a real message uuid), resume can only load a handful of recent messages and the rest of the history becomes unreachable even though it is still in the file. Separately, if a tool result was written into the .jsonl at full size (multi-MB), resume can hang indefinitely while trying to load it.
How to spot it: Only the last few turns are present after resume, OR resume never finishes. Check file size with wc -c (see below); a transcript with one or two multi-megabyte lines is the hang signature.
4. CLAUDE.md or settings changed between sessions
If you edited CLAUDE.md or .claude/settings.json between sessions, the resumed transcript still reflects the OLD rules while the system prompt loads the NEW ones. Behavior gets inconsistent.
How to spot it: Behavior differs from before you closed — a different package manager, a different test command, etc.
5. Resume started in a different working directory
Sessions are stored and looked up per project directory (keyed by a hash of the absolute path). The cwd dictates which CLAUDE.md, which .claude/, and which relative file paths are valid. Resume from a different shell location and the relative paths in the transcript no longer point to the same files; a session ID created elsewhere will not even be found.
How to spot it: Claude says “file not found” for paths that worked yesterday, or claude --resume <id> reports No conversation found with session ID.
6. Subagent / Task results were ephemeral
Task-tool subagents return results into the parent transcript at the time they run. Once the parent transcript is compacted, the subagent’s findings collapse into a one-line summary. The original detail is unrecoverable.
How to spot it: You remember a deep research result from a subagent run; on resume, only a brief mention exists.
7. The session file aged out or you upgraded Claude Code
Local transcripts are deleted after 30 days by default (cleanupPeriodDays). After a Claude Code upgrade, older session files can also be partially incompatible — resume succeeds technically but some fields fail to load.
How to spot it: --resume <id> worked last week and now reports no conversation, the file is gone from ~/.claude/projects/, or you upgraded Claude Code in between.
Before you start
- Note the elapsed time between sessions; more time means more compaction risk (and the file may have aged out past 30 days).
- Have a concrete sample of “lost memory” — a specific decision or task that should have carried over.
- Check whether you updated Claude Code or changed
CLAUDE.md/settings since the previous session. - Decide what you actually need: full state continuation, or just enough context to keep going?
Information to collect
- The session file. Transcripts live at
~/.claude/projects/<project>/<session-id>.jsonl, where<project>is derived from your working-directory path. (If you setCLAUDE_CONFIG_DIR, look there instead.) - Size of the session file:
wc -c ~/.claude/projects/<project>/<session-id>.jsonl. Multi-MB single lines point to Cause 3. - Whether compaction happened: search the transcript for
compactor a summary block, or run/contextin a live session. - Claude Code version now vs at original session start (
claude --version). - Any external state files (a
PLAN.md, session notes,agent.log) that should be paired.
Step-by-step fix
Ordered by ROI — cheapest first.
Step 1: Re-prime context with a “current state” message
The best 90-second fix for any resume. Paste this before you say “continue”:
Quick context dump before we continue:
Project: <name>
Goal of this session: <goal>
Where we left off: <specific step or file>
Decisions already made (do not re-propose):
- <decision 1>
- <decision 2>
Files in scope: <list>
Next concrete step: <action>
This costs 60 seconds and saves an hour of re-derivation.
Step 2: Read the right files BEFORE asking Claude to act
Pre-emptively re-read the load-bearing files so their full bytes land in live context (fixes Cause 2):
Read these files to refresh context:
- src/auth/login.ts (the one we are refactoring)
- src/auth/login.test.ts (the test we are keeping green)
- docs/architecture.md (the constraints)
Then summarize back to me what you understand. Do not act until I confirm.
This forces full content into the context window, not just the summary of “I read it yesterday.”
Step 3: Resume from the correct cwd
Sessions resolve per project directory, so the directory has to match the original (fixes Cause 5):
cd ~/projects/myrepo
claude --resume <session-id>
Pick the right entry point:
| Command | What it does |
|---|---|
claude --continue (-c) | Resumes the most recent session in the current directory |
claude --resume (-r) | Opens the interactive session picker |
claude --resume <name> | Resumes a named/ID session directly |
claude --from-pr <number> | Resumes the session linked to a pull request |
/resume (in-session) | Switches to another conversation without leaving |
Confirm Claude is where you think it is:
What is your current working directory? Print it.
If --resume <id> reports No conversation found with session ID, you are in the wrong directory (or the file aged out past 30 days). In the picker, Ctrl+W widens to all worktrees of the repo and Ctrl+A widens to every project on the machine.
Step 4: Re-sync with the current CLAUDE.md
After resume, force a fresh read so edits made between sessions take effect (fixes Cause 4):
Please re-read CLAUDE.md from disk and acknowledge any changes since the last loaded version. Treat the current file as authoritative.
Step 5: Use a session-state file checked into the repo
Maintain a .claude/session-notes.md (or similar) that captures decisions, open questions, and the current step. Update it before closing each day. On resume:
Read .claude/session-notes.md and recap to me before doing anything else.
This survives compaction because it lives outside the conversation — the single most durable fix here.
Step 6: For a broken or hung session file, branch or start fresh
If only the last few turns load, or resume hangs (Cause 3), do not keep fighting that .jsonl:
- Run
/exportwhile the session is still partly loaded to salvage what you can to a text file, then start a fresh session and feed it your notes. - Use
/branch(orclaude --continue --fork-session) to fork a clean copy if the original is merely heavy but not corrupt. - If the file is multi-MB with giant tool-result lines, abandon it; rebuild context from
PLAN.mdand notes in a freshclaudesession.
Step 7: Accept resume is bounded; restart for multi-day work
For work that spans days, do not lean on resume across more than 1-2 close/reopen cycles. Instead:
- End each working session by writing a “current state” note in the repo (and commit work in progress).
- Start each new session fresh with
claude(not--resume). - Open with “Read .claude/session-notes.md and continue”.
A fresh session has a clean context window and no compaction debt.
Step 8: For very long projects, externalize the plan
Keep a PLAN.md checked into the repo:
# Refactor auth to async/await
## Completed
- [x] login.ts converted
- [x] signup.ts converted
- [x] login.test.ts updated
## In progress
- [ ] reset-password.ts (started, partial)
## Not started
- [ ] sso.ts
- [ ] mfa.ts
## Decisions
- Using axios for HTTP, not fetch (team preference)
- No new dependencies allowed
The plan never lives in the conversation; it lives in git, and every session reads it.
How to confirm it’s fixed
- After a fresh resume + reprime, ask Claude to recite the current step and the decisions; match against what you wrote.
- Run the next concrete step and confirm it does not redo prior work or re-read files unprompted.
- Run
/contextand confirm the load-bearing files and notes are actually present in the window, not just referenced. - Open the session file and confirm its size is reasonable (no multi-MB single lines).
- After 1-2 days, compare “kept resuming” vs “fresh + notes” — fresh + notes should win in most cases.
Long-term prevention
- Externalize state. Anything that must survive 24 hours belongs in a file in the repo, not in the chat.
- Treat resume as a one-day tool. For multi-day work, restart with notes.
- Name your sessions (
claude -n auth-refactor, or/renamein-session) so they are easy to find and resume by name instead of hunting IDs. - Keep
CLAUDE.mdandPLAN.mdupdated as you go; do not save it for end of day. - Tag major decisions with explicit markers in the chat (
DECISION: using axios, not fetch) so they survive summarization better. - Commit work in progress at end of day; the diff is also a memory aid.
- See related context-loss patterns in Claude Code context broken and Claude Code output truncated by context.
- Audit
~/.claude/projects/periodically; resuming from old files is more trouble than starting fresh, and they auto-delete after 30 days anyway (cleanupPeriodDays).
Common pitfalls
- Trusting that resume picks up “with full memory” — it does not.
- Putting the entire plan in the chat (“here are the 30 steps”) instead of in a file.
- Resuming and immediately giving a vague instruction (“continue”) — after compaction, Claude has no good way to know what that means.
- Editing
CLAUDE.mdbetween sessions without telling the resumed Claude to re-read it. - Treating subagent findings as durable; they are not.
- Forgetting to
cdto the right directory before--resume; see Claude Code project CLAUDE.md not loading for the cwd resolution rules. - Assuming
/rewindcan undo everything — it rolls back the conversation and Claude’s file edits to a checkpoint, but it cannot undo bash side effects (deleted files, installed packages, pushed commits). - Upgrading Claude Code mid-week and being surprised that a Friday session does not resume cleanly on Monday.
FAQ
Q: Where are Claude Code sessions actually stored?
As JSONL files at ~/.claude/projects/<project>/<session-id>.jsonl, where <project> is derived from the working-directory path. Set CLAUDE_CONFIG_DIR to relocate the whole ~/.claude tree. Files are deleted after 30 days by default; change that with cleanupPeriodDays in settings.
Q: What’s the difference between --continue and --resume?
claude --continue (-c) reopens the most recent session in the current directory with no prompt. claude --resume (-r) opens a picker, or resumes a specific session when you pass its name or ID. Inside a running session, /resume switches conversations without exiting.
Q: Is there a setting to disable compaction?
No. Compaction is what lets long sessions exist at all (it kicks in near ~98% of the context window). The fix is to externalize what must survive, not to fight compaction. Use /compact <instructions> to steer what it keeps, or /clear to start clean when you are done with a thread.
Q: Why does resume only load the last few messages, or hang forever?
Almost always a damaged .jsonl: a broken parentUuid chain stops the loader after a few messages, and a giant tool-result line (multi-MB) makes loading hang. Check the file with wc -c. Salvage with /export, then rebuild context in a fresh session from your notes.
Q: How long can a session realistically run before resume gets unreliable?
In our experience, 8-12 hours of active use or roughly 3 close-and-reopen cycles. Beyond that, fresh + notes is more reliable.
Q: Why does Claude ask me a question I already answered yesterday?
The answer was compacted out. Either re-answer in the new turn, or surface it from your notes file before asking Claude to proceed.
Tags: #Claude Code #session #memory #Troubleshooting #context