Industry Insights 14 min read

Claude Code Compact Window: Config Accepted ≠ Effective — Merging Rules & 3 Checks

Claude Code's auto-compact window can be set in six different places, each with distinct parsing rules, priority levels, and direction constraints (only lowering, never raising). Invalid values are silently ignored without errors. The article breaks down the merging logic, version-specific changes, and three verification methods: startup warnings, debug logs, and transcript events.

Architecture Development Notes
Architecture Development Notes
Architecture Development Notes
Claude Code Compact Window: Config Accepted ≠ Effective — Merging Rules & 3 Checks

Multiple Places to Set a Window

The /autocompact command saves a window per model into modelSettings; the settings file's autoCompactWindow key sets a window for all models; the --autocompact startup flag affects only the current launch; the environment variable CLAUDE_CODE_AUTO_COMPACT_WINDOW serves scripts and cloud environments; and the sub-agent layer offers two entry points: a frontmatter field or an item in --agents (including SDK agent definitions). Version 2.1.296 (Oct 9) added the sub-agent field to both locations.

The settings file itself has five priority layers (high to low): managed settings, command line, project local, shared project, user settings. A key defined at a higher layer overrides lower layers. However, the documentation explicitly states that environment variables are not part of this chain. When both an environment variable and a settings key exist for the same behavior, precedence is decided pairwise, not by layer. For the window, the variable overrides the command, startup flag, and saved settings values unless the variable's value is deemed unusable.

Thus determining "which value is in effect" requires two steps: first, identify the layer that supplies the value; second, check whether that value passes the validation rules of its entry point.

Who Can Raise, Who Can Only Lower

Global entry points (command, flag, settings key, environment variable) accept values between 100,000 and 1,000,000 tokens. Raising the window above the default is allowed but capped by the model's context window — a hard boundary from the model, not the configuration.

Moving toward local scope eliminates the ability to raise. The sub-agent field (added in 2.1.296) was intended to let sub-agents compact earlier than the main session. Version 2.1.312 (Oct 27) changed the merge behavior: previously, any set environment variable completely disabled the field unless Claude Code ignored the variable's value; now the field can further lower the window on top of the variable's value, but still can never raise it.

Two related parameter families are even more unidirectional. The percentage variable CLAUDE_AUTOCOMPACT_PCT_OVERRIDE can only advance the trigger point; values above the default percentage are ignored, and it only works in sessions where compaction occurs before the model limit. Toggle parameters autoCompactEnabled and DISABLE_AUTO_COMPACT can only turn auto-compaction off — once off, the other cannot turn it back on. Version 2.1.311 (Oct 26) also restricted DISABLE_COMPACT in settings and model definitions to off-only. The rationale: advancing the trigger only costs an extra summary; delaying risks hitting the model's context limit; disabling auto-compaction is a cost or compliance decision.

These one-way limits are not general configuration rules. Settings are resolved by layer priority — higher layers simply override lower ones, regardless of strictness. The documentation mentions a "stricter wins" exception for managed priority, but it applies only to a closed list of session-restricting keys, none related to compaction. Within a single file, specificity wins over generality: /autocompact saves into the current model's entry in modelSettings, which overrides the top-level autoCompactWindow key in the same file, even if the model-specific value is looser.

Therefore conflict resolution must separate two questions: which source provides the value (layer + specificity), and which direction that parameter allows (its own definition). Merging them into a single "stricter wins" rule leads to wrong conclusions for the window.

When Values Are Ignored There Is No Prompt

The documentation lists conditions that invalidate the sub-agent field: value not lower than the inherited window; the entire session runs as that sub-agent (via --agent or agent setting); and the most easily missed — using a suffixed form in frontmatter. The field only accepts an integer; 200k parses as 200, far below the minimum, so it is treated as absent. The sub-agent loads and compacts normally with no error. To confirm, run claude --debug and search ~/.claude/debug/<session-id>.txt for invalid autoCompactWindow.

Three entry points parse the same number differently: /autocompact and --autocompact: bare numbers 100–1000 are interpreted as thousands (200 = 200,000); they accept k / M suffixes.

Environment variable: bare numbers are token counts (200 = 200 tokens); suffixes recognized since 2.1.304.

Sub-agent frontmatter: must be an integer; suffixes not recognized, parsed as prefix number.

The environment variable path had an older pitfall. Before 2.1.304 (Oct 19), setting CLAUDE_CODE_AUTO_COMPACT_WINDOW=200k was silently coerced to the 100k minimum. Since 2.1.304 it recognizes suffixes and emits warnings when values are out of bounds or ignored. Previously, ignored values produced zero output.

Now the variable path emits three distinct warning phrasings that reveal the effective value:

reads as <N> tokens, so Claude Code treats it as the 100k minimum

(clamped to floor); is too large, so Claude Code treats it as the 1M maximum (clamped to ceiling); isn't a usable size, so Claude Code ignores it (fallback to flag, command, settings key, or default). This startup warning is the session's spec sheet for the compaction window.

Verify Effectiveness by Behavior, Not Config

Three observation points confirm whether configuration took effect, ordered by discoverability: startup warnings (distinguish clamped vs. ignored); claude --debug logs (cover sub-agent field discards — ignored field names appear in logs); sub-agent's own transcript (emits a compact_boundary event with preTokens at compaction time). The first two show whether config was accepted; the third shows exactly where compaction fired.

The status bar's used_percentage is not a reliable indicator. Documentation states it calculates against the model's full context window, so during environment variable effectiveness it does not signal when compaction will occur. Seeing a low percentage and assuming the window was raised is a common misjudgment.

One entry point does speak up when ineffective: when a higher-priority scope (e.g., managed settings) has already set a window for the model or all models, /autocompact saves your value but the session continues using the higher scope's value. The documentation says the command will call out this situation. Remembering this difference matters because the most common debugging mistake is applying experience from a vocal entry point to a silent one.

Another discrepancy: the documentation page still reads that setting the variable makes the sub-agent use the variable's window and the field has no effect unless Claude Code ignores the variable's value. But 2.1.312 release notes state that when the variable is effective, the field can now further lower on top of it. Side by side, the difference lies in the variable-usable branch: one says field completely inactive, the other says field can still lower. Fortunately direction is consistent — neither can push the window later. A reader relying only on the docs would assume mutual exclusion and stop trying to set the sub-agent field.

Bringing This Semantics to Your Own Runtime

Adopting this model in your own runtime, the same two concerns deserve separation. Value provenance — resolved by layer and specificity — is a simple, explainable rule. Directional constraints belong to each parameter's definition; budget-type parameters especially should enforce direction in the type or validation layer, not just in a documentation sentence "lower only." Silent ignoring need not be copied: making "accepted" and "ignored" two distinct, queryable outcomes is simpler than letting a parameter quietly fall back to a default. At minimum, leave a searchable string for ignored values, like invalid autoCompactWindow.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

debuggingenvironment variablesClaude Codesub-agentsilent failuresauto-compactconfiguration mergingversion 2.1.296
Architecture Development Notes
Written by

Architecture Development Notes

Focused on architecture design, technology trend analysis, and practical development experience sharing.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.