Claude Code Lost Project Context Mid-Task

Agent forgets earlier decisions, re-reads CLAUDE.md, contradicts the plan. Auto-compact dropped the load-bearing details. Run /rewind, re-anchor, or restart with a tight handoff.

You’re 45 minutes into a Claude Code session. Earlier you decided “we’re not using GraphQL, stick with REST.” Suddenly Claude proposes a GraphQL resolver. Or it re-reads CLAUDE.md and package.json for the fourth time as if it’s never seen them. Or its plan now contradicts the plan it agreed to at minute 10.

The conversation got long enough that auto-compact kicked in. Claude Code summarized the earlier turns to fit the context window, and the specific constraints (no GraphQL, use vitest, edit in apps/web/) didn’t survive the summary. The agent is now working from a lossy memory of what you said.

Fastest fix (as of June 2026): if the bad compaction just happened, press Esc twice, pick Restore conversation to roll back to before the summary, and immediately re-state your constraints in one message. If you’re already too deep, start a fresh session with a 5-line handoff (Step 1 below). Don’t try to argue the agent back into remembering — re-anchor with explicit state instead.

How compaction actually works

Knowing the mechanism tells you which fix to reach for. As of June 2026, Claude Code has three layers, applied lightest-first:

  1. Microcompact — runs silently before API calls once the session is long. It clears old tool results (keeps roughly the last 5, replaces the rest with placeholders) without calling the model. This is why a file you read early “disappears” but your decisions usually survive.
  2. Auto-compact — the heavy pass. When context nears the ceiling of the default 200K-token window (Claude Code reserves headroom for the summary, so the trigger lands somewhat below a full window, not at the very top), Claude Code pauses, summarizes the entire conversation into a structured block, and continues from that summary. This is the one that drops your earlier constraints.
  3. Manual /compact — the same heavy pass, but you trigger it on your terms, and you can tell it what to keep.

The status line shows Context left until auto-compact: X%. When that number gets small, the heavy pass is imminent.

Common causes

Ordered by hit rate, highest first.

1. Conversation hit the limit; auto-compact summarized earlier turns

Once context fills (~95% of the window), the whole conversation gets summarized into one block. The summary preserves the gist but loses specifics — “discussed approach” instead of “agreed no GraphQL, use vitest, no inline styles.” The agent then makes decisions inconsistent with what got summarized away.

How to spot it: A “Conversation compacted” / “Compacting conversation…” message appeared. After it, expect lossy memory. Run /context to confirm the conversation block shrank.

2. Long tool-call traces ate context faster than expected

Every Read, Grep, Bash adds to context. Five Reads of large files can be 20K tokens. Auto-compact triggers earlier than the conversation length suggests.

How to spot it: Session feels short but tool calls are dense. Run /context — high usage comes from the Files / tool output category, not your messages.

3. The summary kept the high-level goal but lost the specific constraints

Auto-compact preserves “user wants to add a billing feature” but drops “user said: do NOT use GraphQL, ONLY edit apps/web/, tests in vitest.” Now the agent proceeds with the goal but free of the specific guardrails.

How to spot it: Output is on-task but violates constraints you set earlier. Constraints were what got dropped, not the task.

4. The constraint lived only in a path-scoped rule or nested CLAUDE.md

This is the subtle one. Per Anthropic’s context-window docs, compaction does not treat all instructions equally:

Where the instruction livedAfter auto-compact
Project-root CLAUDE.md, unscoped rulesRe-injected from disk (survives)
Auto memory (MEMORY.md)Re-injected from disk (survives)
Rule with paths: frontmatterLost until a matching file is read again
Nested CLAUDE.md in a subdirectoryLost until a file in that subdir is read again
A decision you only said in chatLost (summarized away)

So a constraint in .claude/rules/api-conventions.md (scoped to src/api/**) vanishes after compaction and only comes back the next time Claude touches a matching file.

How to spot it: The dropped rule was path-scoped or in a nested CLAUDE.md, and the agent stopped following it right after compaction. Fix by moving it to the project-root CLAUDE.md.

5. Tool errors ate context without producing useful info

A Bash command failed 5 times in a row; each error trace went to context. Microcompact should clear old tool results, but a wall of identical permission-denied messages still pushed you toward the heavy pass faster.

How to spot it: Many repeated tool errors in the session. Each adds noise but no signal.

6. Plan mode produced a long plan that filled context before code started

A 100-line plan + your modifications + tool reads to validate the plan = context already half-full before any real work. The first long code generation triggers compaction, dropping the plan.

How to spot it: Session opened with extensive plan work; the bug starts when code generation begins.

Shortest path to fix

Ordered by ROI. Step 0 is the new “undo” button; Step 1 is the clean restart; Steps 2-3 are durable hardening.

Step 0: If compaction just happened, rewind it

Since Claude Code v2, every prompt creates a checkpoint, and you can roll the conversation back:

  1. Press Esc twice (or run /rewind).
  2. Pick the message from before the compaction.
  3. Choose Restore conversation — this rewinds the chat history while keeping your current files on disk. (“Restore code” or “Restore both” also revert file edits; pick the one you want.)
  4. Re-state your constraints in your next message so they’re fresh in context.

Caveat: checkpoints only capture edits made through Claude’s file tools. Side effects from Bash (a git push, an npm install, an API call) are not reverted. Checkpoints are pruned after ~30 days.

Step 1: Stop, snapshot, restart

If you’re already far past the bad compaction, don’t try to recover the thread — start fresh with a tight handoff:

  1. Write a 5-line “where we are” block:
## Status (2026-06-14 15:30)

Task: Add billing feature to apps/web/
Decisions:
- No GraphQL — REST only
- Tests in vitest, alongside source
- Follow `apps/web/src/features/auth/` for structure
Progress:
- Done: created `apps/web/src/features/billing/index.ts`, `types.ts`
- Next: implement `billing.service.ts`
Blockers: none
  1. Run /clear (wipes the conversation but keeps you in the same project) or open a new session.
  2. Paste the status block as the first message. Add “continue from here.”

A cleared session has full, verbatim context for the snapshot — no fading memory.

Step 2: Promote per-session decisions to CLAUDE.md

Every constraint that got dropped is a CLAUDE.md gap. Put it in the project-root CLAUDE.md (not a path-scoped rule), because that’s what gets re-injected after compaction:

## Architectural decisions

- API style: REST only (not GraphQL — past attempt was abandoned 2025-Q4)
- Test framework: vitest only (not jest — see `apps/web/AGENTS.md`)
- Working directory for new web features: `apps/web/src/features/`

Next session reads this on startup, and it’s re-injected on every compaction. Run /memory to confirm which CLAUDE.md files actually loaded. Keep the file under ~200 lines; an oversized CLAUDE.md just eats the budget faster.

Step 3: Snapshot progress every 30 min into a file

For long tasks, write progress to disk so it survives any context reset:

# At session start, claude creates this file
echo "## Progress log" > .agent-progress.md
echo "Started: $(date -Iminutes)" >> .agent-progress.md

Prompt:

Every time you complete a meaningful step, append to `.agent-progress.md`:
- Timestamp
- What was done
- Files touched
- What's next

If we lose context, this file is the authoritative status.

Step 4: Minimize context-eating tool calls

Reduce noise that triggers earlier compaction:

- Prefer `Grep` over `Read` for finding things — much smaller output
- When `Read`-ing, use line ranges, not whole files
- Don't `Read` the same file twice; remember its content
- Cache long outputs by writing to `/tmp/<name>.txt` and referring to them
- If a `Bash` command keeps failing, stop and ask — don't retry 5x

Step 5: Use subagents for orthogonal sub-tasks

Long tasks with multiple concerns benefit from delegating to subagents (the Task tool). Each subagent runs in its own separate context window — it reads files there, and only its final summary returns to your main session:

For the database migration step, spawn a subagent with just that task.
Return: the migration file path and the applied migration name.

Per Anthropic’s docs, a subagent that reads 6,000 tokens of files might return a 400-token summary — the file reads never touch your main window. The built-in Explore and Plan agents are designed for exactly this.

Step 6: Compact on your terms, before the auto-pass

The status line counts down Context left until auto-compact: X%. Don’t wait for it to hit zero — Claude reasons worse in the last ~20% of the window. As of June 2026, the practical target is to act around 60-75% usage:

  • /compact focus on the billing feature, keep the no-GraphQL and vitest constraints — a focused manual compact keeps what you name instead of what the auto-pass guesses.
  • Save any in-flight decisions to CLAUDE.md or .agent-progress.md first.
  • For unrelated next work, /clear instead of compacting — a clean window beats a summarized one.

Compacting at 60% on your terms is far cheaper than recovering from a broken 95% summary.

How to confirm it’s fixed

After re-anchoring or restarting:

  1. Ask: “Before you write code, list the constraints you’re working under.” A healthy session names REST-only, vitest, and the apps/web/ scope back to you.
  2. Run /context and check that the conversation block is small and your constraints are in the freshly re-injected CLAUDE.md.
  3. Watch for the next contradiction. If it reappears, the constraint is still living only in chat — promote it to the project-root CLAUDE.md (Step 2).

FAQ

Why does Claude keep re-reading the same files? After microcompact clears old tool results (keeping ~the last 5), or after a full compaction summarizes them away, Claude no longer has the file contents in context, so it re-reads them. That’s expected. To reduce it, keep sessions shorter, scope your prompts so Claude reads fewer files, and delegate big reads to a subagent.

Can I just turn auto-compact off? You can disable it in settings (autoCompact: false or via /config), but then a full window simply stops the session instead of continuing from a summary. That trades a lossy memory for a hard wall. A better habit is to /compact with focus or /clear at a clean boundary yourself.

Does the 1M-token context window fix this? It delays it. Sonnet 4.6 and Opus 4.7 support a 1M-token context window (select the [1m] model variant where your plan allows), so compaction happens much later. But the same summarization runs at the higher ceiling, and a giant window full of stale reads still degrades reasoning. Treat the bigger window as headroom, not a license to never compact.

Why did it forget a rule that’s written in a file? Path-scoped rules (.claude/rules/*.md with paths: frontmatter) and nested CLAUDE.md files are summarized away on compaction and only reload when Claude next reads a matching file. The project-root CLAUDE.md and auto memory are re-injected from disk every time. Put must-survive constraints in the project root.

What’s the difference between /compact and /clear? /compact summarizes the conversation and keeps the summary as context (good when you want to continue the same task with less bloat). /clear wipes the conversation entirely and starts fresh in the same project (good when switching to unrelated work). Use /rewind instead when you want to undo a specific recent change rather than condense everything.

Prevention

  • Promote per-session decisions to the project-root CLAUDE.md so they survive compaction; keep it under ~200 lines.
  • Don’t bury must-survive constraints in path-scoped rules or nested CLAUDE.md — those get summarized away.
  • Keep a .agent-progress.md for tasks longer than 20 minutes; it’s the fallback when context resets.
  • Restart or /clear at clean boundaries (after a step completes) instead of pushing through past compaction.
  • Minimize tool-call noise — Grep > Read, line ranges > full files, no re-reading.
  • Delegate orthogonal sub-tasks to subagents so each has its own context window.
  • Treat Context left until auto-compact: ~20-30% as a wrap-up signal; /compact with focus or /clear before it hits zero.

Tags: #Troubleshooting #Claude Code #Debug #Context missing