Compaction failed unexpectedly
The load-bearing word in this message is unexpectedly. Claude Code has
specific wording for each compaction failure it knows how to describe — too long
to summarize, too few messages to summarize, refilling faster than it can
compact. Getting the generic message means none of those matched, which rules
out the length of your conversation as the explanation and points at the
summarization request itself failing. It is not a corrupted session, and it is
not something /clear diagnoses for you.
Data as of 2026-09. Vendor limits and defaults change; check the official docs for current values before acting on any number below.
What the generic wording rules out
Three compaction failures have their own named messages. If you saw one of them, you are on the wrong page and the fix is different:
Error during compaction: Conversation too long. Press esc twice to go up a few messages and try again— there was not enough free context to hold the summary. A length problem, fixed by removing turns first.Not enough messages to compact.— the conversation has too few turns to summarize, which can happen even with a full window when a single large paste filled it.Autocompact is thrashing: the context refilled to the limit...— compaction worked, and something immediately refilled the window several times in a row, so Claude Code stopped retrying.
None of those describe a generic failure, because Claude Code would have said so. What is left is the call itself.
Compaction is a model request, with everything that implies
Summarizing a conversation means sending it to the model and getting a summary back. That request uses the same credential, the same quota, the same provider and the same network path as every other turn in your session. A compaction failure is frequently not about the conversation at all — it is the same failure your next ordinary turn was about to hit, surfaced under a different name.
This is easy to miss because of when compaction runs. Auto-compaction is on by default and fires at a threshold, so it is often the first request to cross into whatever condition you have just entered: the moment your session quota ran out, the moment a provider started refusing, the moment a stray credential took over. You read “compaction failed”, conclude the conversation is the problem, and start deleting context that was never the cause.
There is a second place to look that most people never open. When automatic compaction runs and fails, the full-context message names the underlying cause directly:
Prompt is too long · automatic compaction failed: <the underlying error>
That trailing clause is the actual error. If you have it, diagnose that string instead of this one.
Is retrying useful?
No — not the way you are about to do it.
Claude Code retries transient failures up to 10 times with exponential backoff
before showing you anything; that is the CLAUDE_CODE_MAX_RETRIES default,
capped at 15 as of v2.1.186 unless CLAUDE_CODE_RETRY_WATCHDOG is set. Typing
/compact again is attempt eleven against a condition that already survived ten.
This trips up people who come from the Anthropic API SDKs, where the retry default is twice. The CLI is not the SDK, and its budget is an order of magnitude larger. When a CLI error reaches your terminal, the cheap explanations have been eliminated for you already.
Retry only after you change something: a different model family, a different
credential, a shorter conversation, one fewer MCP server. Then a single /compact
tells you whether the change mattered.
Narrowing it down without guessing
Each of these has an observation that confirms or eliminates it. Run them in order; the first two take seconds.
- Plan quota or a spend cap. Do ordinary turns fail too, with a message
naming a reset time —
You've hit your session limit · resets 3:45pm, or the weekly equivalent? Then compaction failed because everything is failing./usageshows your plan windows and reset times. Session and weekly limits are shared across models, so/modelwill not rescue you; a limit specific to the Opus or Sonnet family will, because it applies only to that family. - The wrong credential is in play. Run
/status, which shows which credential is actually active. The classic version of this is a subscriber with a strayANTHROPIC_API_KEYin the environment: requests route through Console credits instead of the subscription, and failures arrive with billing-shaped messages that make no sense for a plan account. - The session’s content, not your account. Start a fresh session in another directory and run something small. If that works, the cause is inside this session — configuration, attachments, or a specific MCP server — rather than your account or the provider.
- Attachments rather than tokens.
Request too large (max 32MB)is a raw request-body limit measured before tokenization, not a context-window limit. When the messages alone exceed it, Claude Code says compacting cannot make it fit and does not retry. Images and accumulated attachments are the usual way a session gets there. - Thinking configuration. As of v2.1.198 the summarization request inherits the session’s extended thinking configuration. A session configured for heavy thinking applies that configuration to compaction too, so compaction is not the cheap background operation it is often assumed to be.
Fixes, matched to what you found
- Quota or spend limit — switch to a model outside the exhausted family with
/model, or wait for the named reset. Budget for one cost: each model has its own prompt cache, so the first request after switching re-reads the whole conversation uncached. - Wrong credential — unset the stray variable and restart the session, then
confirm with
/statusrather than by feel. - Session-local cause — narrow it with
claude --safe-mode, which starts with all plugins, MCP servers and hooks disabled. If compaction works there, your customization is implicated and you can re-enable pieces one at a time. - Attachments — press Esc twice with an empty input to step back past the messages carrying the images, then compact.
- Nothing reproduces and it happened once — treat it as spent retries, keep working, and only investigate if it returns. A failure that already survived ten backoff attempts but never recurs is not worth an afternoon.
Confirming the session is healthy again
Run /compact manually and watch it finish. Then check /context and confirm
the total actually dropped — a compaction that “succeeded” without reducing the
window means something refilled it immediately, which is the thrashing case.
Then take two ordinary turns in a row. One turn is not enough evidence: the
threshold that triggers auto-compaction has to be crossed again before the
failure can reappear, and a single short prompt will not cross it.
If it comes back at the same point every session, stop treating it as an incident
and change the trigger: /autocompact <value> writes the autoCompactWindow
setting, and the --autocompact flag and CLAUDE_CODE_AUTO_COMPACT_WINDOW
environment variable override it in that order. The accepted range is 100K to 1M
tokens, capped at the model’s own context window. Compacting earlier means
compacting with room to spare.
Related failures worth reading next
- Error during compaction: Conversation too long is the other half of this problem — the named case, where compaction fails specifically because the window is full, and where the deadlock has a documented escape.
- prompt is too long: 209117 tokens > 200000 maximum is what you get when compaction cannot run at all and the request is rejected outright.
- Error: File content exceeds maximum allowed tokens explains the guardrail that keeps one file read from refilling the window right after a compaction.
- Before you tune the auto-compact window, use the context window calculator to see how much of the window your baseline consumes before the conversation starts.