Back to Blog
|7 min read

How to Stop Claude Code From Losing Context (2026)

#claude-code#context-window#compaction#persistent-memory#mcp
How to Stop Claude Code From Losing Context (2026)

Yesterday I was in the middle of a release with Claude Code. Two hours in, the session hit the context limit and compacted itself. In the old days that was the moment everything went sideways: the summary kept the gist, dropped the task, and the next answer started from "let's review the auth changes" when we had been shipping a hook for twenty minutes. This time I asked it what it still knew, and it quoted my first request of the session, the last one before the cut, and the five memories that mattered for the branch I was on.

That difference is not luck. If you've been searching for how to stop Claude Code from losing context, here's the honest version: Claude Code loses context at four specific moments, and each one has a different fix. Some are a flag. One is a hook. None of them is "buy a bigger context window."

TL;DR: Context gets lost when the window compacts, when you start a new session, when you switch tools, and when your CLAUDE.md is out of date. Keep rules in CLAUDE.md, resume sessions instead of restarting them, install a post-compaction hook that re-injects the task, and keep decisions in a memory the agent can query from any session. The table below says which fix covers which moment.

The four moments Claude Code loses context

It helps to be precise about when it happens, because people blame the model for all four and only one is really about the model.

  1. Compaction. The window fills, Claude Code summarizes the conversation to free space, and the summary is lossy. Decisions and the original task are the usual casualties. I wrote the long version in why your session forgets mid-task.
  2. A new session. You close the terminal, come back tomorrow, type claude, and it's a blank slate. Everything you explained lives in a transcript it isn't reading. The session handoff post covers the manual workarounds.
  3. A tool switch. You move to Cursor for the UI work. Nothing from Claude Code follows you, because each tool keeps its own state. Sharing context between Claude Code and Cursor is its own problem.
  4. A stale CLAUDE.md. The file loads every session, which feels like memory until the codebase moves on and the file doesn't. Now the agent confidently follows rules that stopped being true in August. Why CLAUDE.md goes stale has the pattern.

Within a single uncompacted session, by the way, Claude does remember what you said ten messages ago. That part works. The question of whether Claude remembers between chats in the same thread is really about the four moments above.

Which fix covers which moment

Where context lives Survives compaction Survives a new session Survives a tool switch Where it breaks
CLAUDE.md yes yes no (Cursor reads .cursorrules) goes stale; nobody updates it
claude --continue / --resume partly (the transcript is kept, the summary is what the model sees) yes, same machine only no a second machine, a teammate, a different tool
Claude Code auto-memory notes yes yes no one tool, one machine, the agent decides what to write
A post-compaction hook yes, that's its job no no only Claude Code; only what the hook re-injects
Memory over MCP (ContextForge or similar) yes, if something re-injects it yes yes only as good as what the agent saved

No single row covers everything. The combination that works for me is the first, fourth and fifth rows together, and the second row for the days I just need to pick up where I left off.

Fix 1: Put rules in CLAUDE.md, not facts

CLAUDE.md is loaded on every session, so it's tempting to put everything there: the architecture, the decisions, the schema. Don't. Facts change and the file won't. Keep it for things that are true for the life of the project: how to run tests, what never to do, which tool holds the memory. Mine has one rule that matters more than the rest: at the start of a session, query memory before answering anything about the project. That single line turns a static file into a pointer at something that stays current.

If your CLAUDE.md is more than a screen long, that's the symptom. Move the facts somewhere with a date on them.

Fix 2: Resume, don't restart

The cheapest fix most people skip. claude --continue reopens the most recent session in the current directory; claude --resume lets you pick one. The transcript comes back, including what you explained an hour ago. It doesn't help you on a second machine or in another tool, and it doesn't undo a compaction that already happened, but for "I closed the terminal to get coffee" it's the whole answer.

Fix 3: Make compaction restore the task

This is the moment that used to hurt most, and it's the one where a hook changes the outcome. Claude Code runs a SessionStart hook with the matcher compact right after every compaction, and whatever that hook prints is injected into the fresh context. I covered the mechanics and the setup in the compaction post; the short version is two commands:

claude mcp add contextforge -e CONTEXTFORGE_API_KEY=<your_key> -- npx -y contextforge-mcp
npx contextforge-mcp init

What's new since that post is the second hook init now installs. A UserPromptSubmit hook records each prompt you type to a local file, so when the recall hook runs after compaction it can print your session objective (the first real request) and the last request before the cut, ahead of the memories relevant to your branch, the project's recent memories and its pending tasks. The task itself, which is what the summary drops most often, is the first line the model sees.

This is what came back after yesterday's compaction, trimmed:

## ContextForge: context restored after compaction
Session objective (the user's first request): "ya esta areglado e implementado?"
Latest request before compaction: "ok dale arranca con el 13.2"
Relevant to current work:
- contextforge-mcp 0.13.1 shipped: staged recall deadlines ...
- ROOT CAUSE stale CONTEXTFORGE_API_KEY in Claude Code env ...
Recent memories: (10)
Pending tasks: (5)

Two honest notes. The prompt log stays on your machine and is never uploaded; what leaves is the objective text, at most 600 characters, sent as a search query the same way any memory query is. And the hook never blocks a session: no key, no linked project, a slow network, and it prints nothing and exits.

Fix 4: Keep decisions where any session can ask for them

The hook only re-injects what exists. For a decision to come back next week, in Cursor, on your laptop, it has to be saved somewhere outside the transcript, with the reason attached. That's the part MCP memory does.

One correction to how this usually gets described, including by the first draft of this post: nothing is captured silently. The agent calls a tool, memory_ingest, with a title, the content and the space it belongs to. It does that on its own when the server's instructions tell it to save decisions proactively, and it does it when you say "remember this." Reading works the same way: memory_query is a semantic search, so "why did we make the landing page static" finds the decision even if nobody used those words. Memories live in spaces (topics) inside a project linked to your repo, and a freshness check flags the ones that reference files that changed since, so the agent can confirm, correct or forget them instead of acting on a fact from August.

If you want to see what that looks like when it fails, why AI coding agents contradict earlier decisions is the companion piece: the decision was saved, but without the why.

What this doesn't fix

  • The hooks are Claude Code only. Cursor and Windsurf get the memory over MCP but not the post-compaction re-injection, because they don't expose that event.
  • The objective is the first real prompt the hook logged. If you started the session with "hola" and then pasted a 2,000-word brief, the brief is what comes back, cut at 300 characters.
  • The relevance search is one metered query per compaction. It only runs when there's an objective or you're on a non-default branch, and it has a six-second deadline so a slow search trims the block instead of erasing it.
  • It's a small team's early product. Setup is one command, but the quality of what comes back is exactly the quality of what got saved. If the agent never recorded that the migration uses soft deletes, no search will invent it.
  • None of this replaces reading the code. It replaces re-explaining it.

FAQ

Does /compact delete my context? It replaces the conversation with a summary. The transcript on disk is intact, but the model only sees the summary, so anything the summary dropped is gone for the session unless a hook puts it back.

Does CLAUDE.md load automatically? Yes, at the start of every session in that directory, which is why it's the right place for rules and the wrong place for facts that change.

Does the post-compaction hook work in Cursor? No. Cursor has no compaction hook. Memory over MCP works there; the re-injection step doesn't.

One thing to do today

Open .claude/settings.json in the project you use most. If there's no SessionStart entry with the matcher compact, you're relying on the summary to remember your task. Run npx contextforge-mcp init, work until the next compaction, and ask Claude what it still knows.

Share this article

Related Articles