aieveryminute

Claude Code's auto-compaction fails with `too_few_groups` when one turn fills your context

Compaction succeeded every time the conversation had several turns to summarise, and failed every time a single turn had filled the context with tool results. The failure is reported nowhere except the verbose stream.

Auto-compaction is the loudest complaint about Claude Code. It is blamed for losing hours of work by summarising a conversation into a lossy approximation of itself.

What nobody appears to have checked is whether it runs at all. It does not always, and the case where it gives up is the case where you most need it.

Compaction reports a status the normal output does not carry

Run Claude Code with --output-format stream-json --verbose and it emits system events of subtype status carrying three fields:

{"type":"system","subtype":"status","status":"compacting"}
{"type":"system","subtype":"status","compact_result":"failed","compact_error":"too_few_groups"}

compact_result and compact_error are not in the documentation. They also do not appear in --output-format json, whose summary object has no compaction field at all, so whether compaction ran, succeeded or failed is not observable in the standard machine output.

Filling the context in one turn makes compaction fail

I loaded a session past a deliberately low compaction window (--autocompact 100000, the minimum) two different ways and watched the status events.

How the context was filled Turns Context Compaction
One turn reading four large files 5 122,575 failed / too_few_groups
One turn reading four large files 5 122,591 failed / too_few_groups
One turn reading one large file 2 74,980 failed / too_few_groups
Four short turns, then the same four files 6 115,471 success
Four short turns, then the same four files 6 114,850 success

Every single-turn run failed. Every multi-turn run succeeded. Same files, same window, same prompt for the final turn.

The error name describes it exactly: compaction works by summarising groups of conversation, and a session whose context was filled by one turn’s tool results has too few groups to summarise. There is nothing to compress into a summary, so it gives up.

That is the exact shape of the problem people actually hit. “Read these files and refactor this” fills the window inside one turn. The user who blows their context fastest is the user compaction cannot help, and nothing in the normal output says so.

Compaction did not fire at all on the default setting

The same 122,000-token workload, varying only the window:

--autocompact Context reached Compaction attempted
100000 122,575 yes
auto (default) 122,577 no
1000000 122,591 no

So on the default setting a session carrying about 122,000 tokens of context never triggered compaction. Whatever auto resolves to, it is above 122,591 tokens on this setup. That is worth knowing before you blame compaction for something: at ordinary session sizes it may not have run.

There is no way to switch it off

The flag validates strictly. I tried ten values:

Value Result
auto, 100000, 1000000 accepted
0, off, false, none, disable rejected
50000, 2000000 rejected, out of range

The error is explicit: “It must be ‘auto’, or between 100k and 1M”. There is no disable value. The widely repeated claim that auto-compaction cannot be turned off is correct, and now has the enforcement behind it.

One footgun worth flagging. The same values rejected loudly on the command line are accepted silently in settings.json: autoCompactWindow set to 0, 50000, 2000000, "off" or false all start a session with no warning of any kind. Before reading too much into that, note a deliberately invented key is also accepted silently, so this may be generic tolerance of unknown settings rather than a specific trap. Either way, setting it there tells you nothing about whether it took effect.

What I could not explain, and did not publish

The runs using --output-format json consistently took more turns and more tokens than the identical configuration under stream-json: 8 to 9 turns and 403,112 to 540,700 tokens, against 5 turns and about 181,700. They also never crossed the compaction threshold, reaching about 84,800 tokens of context rather than 122,500.

It reproduced twice in each arm, which is suggestive and nowhere near enough. An output format changing how many tool calls a run takes would be a strange and important claim, and the likelier explanation is that those runs simply took a different path through the same task. There is no finding here, only a thing worth measuring properly another time.

Practical upshot

  1. If you are debugging context loss, run once with --output-format stream-json --verbose. It is the only way to see whether compaction ran and whether it worked.
  2. Do not count on compaction to rescue a single huge turn. That is the case it fails on. Split large reads across turns, which also happens to be the case it can summarise.
  3. You cannot disable it, so --autocompact 1000000 is the closest thing to holding it off.
  4. Setting autoCompactWindow in settings.json gives you no feedback at all; prefer the flag, which validates.

Method

Claude Code 2.1.226, headless, --permission-mode acceptEdits, each run in a fresh temporary project with an empty settings file, reading four generated files of about 63KB each. Compaction outcomes were read from system/status events in the verbose stream rather than inferred from a context drop, because a context drop is ambiguous and an explicit event is not. Every configuration above was run at least twice and the single-turn and multi-turn outcomes were unanimous within their arm.

POSTaieveryminute.com#behaviourbuilt 2026-08-31 17:47 UTC