Subagent auto-compaction uses the main session's context window, so subagents on a smaller-window model are never compacted and die with a 400

Status Open
Reported on v2.1.220
Maintainer reply None cached
Activity 1 comment · opened Aug 2, 2026

Environment

  • Claude Code 2.1.220 (also reproduced on 2.1.207 through 2.1.216)
  • macOS 15 (darwin 25.5.0), arm64
  • Mixed-model setup: coordinator on a 1M-context Claude model, subagents pinned to a third-party model with a 372k window, reached through an Anthropic-compatible gateway

Summary

options.mainLoopModel — the session's model — is what auto-compaction resolves its context window from. A subagent pinned to a different model via model: in its agent definition therefore inherits the coordinator's window rather than its own.

When the coordinator's window is larger than the subagent's, the compaction threshold sits above the subagent's real ceiling and can never be reached. The subagent grows until the upstream rejects the request:

API Error: 400 Your input exceeds the context window of this model.

The whole subagent run is lost — no partial result reaches the caller, and re-running the same task fails identically.

Evidence

1. The coordinator's model decides whether subagents compact

45 days of local transcripts, grouped by session. Subagent model is identical in every row (a 372k-window model); only the coordinator's model differs. Spans Claude Code 2.1.207 → 2.1.216, so the client version is not the variable.

| Coordinator model | subagent transcripts | any compaction | peak tokens |
|---|---|---|---|
| 372k-window model | 11 / 8 | 6 / 1 | 167k / 204k |
| 1M Claude model A | 710 / 527 / 136 | 0 / 0 / 0 | 371.5k |
| 1M Claude model B | 267 / 121 / 110 | 0 / 0 / 0 | 371k |

Peaks in the failing rows pin at ~371.5k, i.e. the subagent model's hard ceiling.

2. When it does compact, it compacts at the coordinator's threshold

In sessions whose coordinator ran the 372k model, subagent compaction fires exactly where a 200k window predicts (window - 13000 = 187000):

compact_boundary trigger=auto preTokens=168139
compact_boundary trigger=auto preTokens=170965
compact_boundary trigger=auto preTokens=174076
compact_boundary trigger=auto preTokens=178187
compact_boundary trigger=auto preTokens=180766

3. Minimal end-to-end reproduction

Coordinator claude-opus-5, subagent pinned to the 372k model, subagent driven past the threshold.

  • Without CLAUDE_CODE_AUTO_COMPACT_WINDOW: subagent never compacts; with enough work it reaches ~372k and returns the 400 above.
  • With CLAUDE_CODE_AUTO_COMPACT_WINDOW=100k: subagent compacts (trigger=auto, preTokens=77132) and completes normally, while the coordinator is unaffected in the same run.

That the env var fixes it is itself the evidence that the window — not the model routing — is what is wrong.

Impact

Any mixed-model orchestration where a subagent's model has a smaller context window than the session's. The larger the coordinator's window, the more reliably its subagents die: a 1M coordinator makes a 372k subagent's compaction threshold unreachable by construction. Locally this produced 58 lost subagent runs in 20 days, several after more than an hour of work.

What does not work around it

  • CLAUDE_CODE_MAX_CONTEXT_TOKENS — only consulted for models whose id does not start with claude-; the window is taken from the coordinator's model, which does.
  • autoCompactWindowsCache (per-model map in ~/.claude.json) — gated on the first-party check, so it has no effect behind a gateway. Writing correct per-model entries changed nothing in our tests.
  • Subagent frontmatter — the 16 supported fields include no context window, compaction, token budget, or per-agent environment field.
  • Agent teams — an in-process teammate shares the lead's sessionId and is recorded with isSidechain: true, so it inherits the same window.

The only effective control is CLAUDE_CODE_AUTO_COMPACT_WINDOW, and it is process-global: it is a floor for every model in the process, so protecting the subagents also caps the coordinator. There is no way to express "compact this subagent at its own model's window".

Suggested fix

Resolve the auto-compact window from the model that will actually serve the request — the subagent's own model when one is pinned — instead of options.mainLoopModel. Failing that, expose a per-agent override (for example a contextWindow or autoCompactWindow field in subagent frontmatter) so mixed-model setups can declare the real ceiling.

Notes for maintainers

Values outside [100000, 1000000] are silently discarded, so a misconfigured CLAUDE_CODE_AUTO_COMPACT_WINDOW looks applied but is not. A warning on out-of-range values would have saved several hours of misdiagnosis here.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗