Why Claude Code Keeps Losing Context Mid-Task¶
The usual advice, when Claude Code loses the thread partway through a task, is to start a fresh session and clear the context. That works, but it treats the symptom and discards everything the agent had learned. It also does not explain why the agent that knew the plan an hour ago forgets it now. There is a named mechanism behind this, and once you can see it you can structure a long run so the loss does not happen in the first place.
What is context rot?¶
"Context rot" is the term Chroma introduced for a measured effect: as the number of tokens in the context window grows, the model's ability to use what is in that window reliably declines. The decline is not uniform — it is task-dependent and grows increasingly unreliable as the input lengthens, rather than dropping off a single cliff. Anthropic adopted the same term in its guidance on effective context engineering, describing it as the reason a long window stops behaving like a perfect record of the session.
The practical meaning for an operator: a fact does not have to leave the window to stop influencing the agent. It can still be present and simply be crowded out. The earlier in a long session a decision was made, the more likely a later turn acts as if it never happened.
Does compaction cause it?¶
Compaction is the second, sharper mechanism, and it is the one most readers are actually hitting. When a session approaches the context limit, Claude Code summarizes the conversation so far and continues from the condensed version. Anthropic describes compaction as the first lever for keeping a long run coherent. But a summary is lossy by construction: a constraint that lived only in an earlier message can be softened or dropped when the conversation is distilled, so the agent stops honoring something it followed an hour earlier in the same session.
Two open issues show the failure mode directly. In
#23047 compaction fails at the context limit and the
only escape is /clear, which destroys all session state. In
#23751 compaction fails far below the limit because
the summarization step has a smaller window than the main model. In both, the recovery path throws away
exactly the earlier state you needed to keep.
Which one is yours — a quick test¶
- Did the agent hold the plan early and drift only after a long run, with no visible compaction message? That points to context rot (mechanism one). The trigger is total tokens in the window.
- Did the loss happen right after a "compacting" step, or after you ran
/clearto escape a stuck session? That points to compaction (mechanism two). The trigger is the summarize-and-continue step. - Was the window full of one large artifact — a big file, pasted logs, a long diff — when it slipped? That is context rot accelerated by a single dominant input. Remove the artifact and re-state the goal.
The two mechanisms compound, but the dominant trigger tells you which fix to reach for first. The same path, from the symptom you saw to the fix to reach for:
flowchart TB
Q{"Agent lost the thread<br/>mid-task — what did you see?"}
Q -->|"slow drift over a long run,<br/>no compaction message"| ROT["Context rot<br/>trigger: total tokens in the window"]
Q -->|"loss right after a compaction step<br/>or a /clear to escape"| COMP["Compaction<br/>trigger: the summarize-and-continue step"]
Q -->|"window held one big artifact<br/>— a file, logs, a diff"| ACC["Context rot, accelerated<br/>by one dominant input"]
ROT --> FROT["Move load-bearing state into CLAUDE.md,<br/>then reset and re-state the goal"]
COMP --> FCOMP["Re-state the goal on reset;<br/>reset deliberately, before it drifts"]
ACC --> FACC["Remove the artifact,<br/>then re-state the goal"]
How do I keep state across a long run?¶
The durable move is to stop relying on the conversation to remember. Put the load-bearing state where compaction cannot summarize it away, and re-state the goal whenever the thread resets.
- Keep the goal and the non-obvious constraints in the instruction file, not only in chat. A rule written into
CLAUDE.mdis re-read at the start of a session and survives a reset; a rule you only typed once lives only in the conversation and is the first thing a summary blurs. - Re-state the goal on every reset. When you start a fresh session after a stuck or compacted one, restate the task and the decisions already made in one block, rather than pushing the cluttered thread further.
- Reset deliberately, before the agent is confused. The signal that a run needs you is the agent losing the thread; resetting early with a clean restatement is cheaper than recovering a session that has already drifted.
You can watch the whole effect on the course Practice Repo, Triage: run a
long, multi-step task once letting the session fill, and again with the goal and constraints written into
app/llm/prompts.py and the instruction file, and count where the agent drifts in each. The full walkthrough,
with the exact files and the expected result at each step, is the lab in
Module 1.
The rule¶
Treat the conversation as volatile and the instruction file as durable. Context rot and compaction both erode
what lives only in chat, so the state that must survive a long run belongs in CLAUDE.md and in a goal you
re-state on every reset. Deciding what belongs in the file, what the agent should fetch on demand, and when to
reset is the skill of context engineering, which is the subject of
Module 1. Next step: move the one constraint you keep having to repeat out of
chat and into your instruction file, then run your next long task and watch whether it still slips.