[BUG] Context usage percentage computed against 200K while session actually runs with 1M context ([1m] model variant)

Status Open
Reported on v2.1.198
Maintainer reply ✓ Yes — bcherny
Activity 5 comments · opened Jul 2, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Environment

  • Claude Code version: 2.1.198
  • Platform: Linux (Debian-based container on WSL2, Docker sandbox)
  • Auth: first-party subscription (claude.ai login)
  • Model: claude-fable-5[1m] (set via /model, persisted in ~/.claude/settings.json as "model": "claude-fable-5[1m]")

Bug description

In an interactive session using a [1m] model variant, the context usage percentage exposed to the statusline (context_window.used_percentage) appears to be computed against the 200K window, not the effective 1M window.

Observed

  • The statusline used_percentage reached 100% when cumulative input tokens (input + cache read + cache creation) were around 200K (88.6% was shown at ~177K, consistent with a 200K denominator).
  • The session then continued normally well past 200K: a later manual /compact recorded preTokens: 219313 in the transcript compactMetadata, and there were no API errors before that.
  • Since requests above 200K input are only possible with the 1M context window, the effective window was 1M while the displayed percentage was 200K-based.

Expected

used_percentage (and any context-low warnings derived from it) should be computed against the effective context window of the session — 1M when the [1m] model variant is active.

Impact

  • Users see "100%" and assume imminent overflow while the real window is only ~20% used.
  • Expectations around auto-compact get miscalibrated: auto-compact (correctly) does not fire at ~200K in a 1M session, which at first looks like the auto-compact regression reported elsewhere (#65585), but is actually a display issue.

Steps to reproduce

  1. Select a [1m] model variant via /model in an interactive session.
  2. Fill the context past ~180K tokens (e.g. have Claude read several large files).
  3. Watch the statusline used_percentage reach 100% around 200K while the session keeps working fine beyond that point.

Additional question

Is CLAUDE_CODE_DISABLE_1M_CONTEXT still supported? Setting it to "1" in project settings env had no observable effect on 2.1.198 (both interactive and headless sessions exceeded 200K input regardless). If it was removed, it would be helpful to have that documented.

View original on GitHub ↗

4 Comments

semikolon · 1 month ago

**Corroboration on 2.1.172 — and a more destructive variant: the 200K-denominator can also drive auto-compaction, not just the display.**

Same core bug as reported (percentage/accounting computed against 200K while the session actually runs on 1M). But in my case it was not display-only — auto-compact fired against the phantom 200K and thrashed.

Environment: CC 2.1.172, macOS, Opus 4.8 (1M context), first-party Max subscription.

Evidence the API window was genuinely 1M:

  • The per-session context-bridge JSON (/tmp/claude-context-bridge-<pid>.json) reads "context_window_size": 1000000.
  • Turns sent ~475K–495K-token prompts and the API accepted them without error.
  • A sibling session launched byte-identically on the same machine sits at 740K/1M (74%) without compacting.

But this session behaved as if the budget were 200K: the statusline showed 100% (200k/200k) and CC auto-compacted 11 times over ~7h of active use (three bursts of 3 compactions within ~5 min each). With ~275K tokens of always-resident memory (large CLAUDE.md), every turn was already over the phantom 200K budget → compaction can't evict resident memory → unrecoverable thrash. Measured cost on that one session: 16.1M cache-creation + 5.4M cache-read tokens to emit 209K of output (≈34 re-caches of the baseline).

Two additions to the original report:

  1. It's per-session and intermittent. Byte-identical launches diverged — one PID stuck at 200K, siblings correctly at 1M. Suggests a startup race between 1M-window enablement and the compaction-accounting subsystem, not a global setting.
  2. It can be destructive, not just cosmetic — when resident context exceeds 200K, the phantom budget triggers a real auto-compaction loop that burns large amounts of cache-creation quota.

Possibly related: #75147 (caps at 200K on fresh sessions), though here the API did not hard-cap (it accepted 475K prompts) — only the accounting/auto-compact used 200K.

grsrzxgvmpg · 1 month ago

Additional evidence from Windows 11 (Claude Code 2.1.218 at capture time, CLI now 2.1.220; claude.ai/code bridge session): the statusline stdin payload self-contradicts within a single session, which pins the mechanism — context_window.context_window_size is populated with a 200k floor until observed usage crosses 200k, then flips to the real value.

Same session (690c2eb6…), same field, two captures of the statusline JSON (dumped verbatim to a sidecar file by our statusline command; cost/rate-limit fields omitted):

Before crossing (total_input_tokens 179,874):

{"context_window": {"total_input_tokens": 179874, "context_window_size": 200000, "used_percentage": 90, "remaining_percentage": 10}, "exceeds_200k_tokens": false, "model": {"id": "claude-opus-5", "display_name": "claude-opus-5"}}

Same session, after crossing (total_input_tokens 758,444 — no compaction occurred at the 200k boundary, confirming the session was 1M all along):

{"context_window": {"total_input_tokens": 758444, "context_window_size": 1000000, "used_percentage": 76, "remaining_percentage": 24}, "exceeds_200k_tokens": true, "model": {"id": "claude-fable-5", "display_name": "Fable 5"}}

Consequences observed downstream: the harness-computed used_percentage hit 90-100% at ~180k, our context-monitoring hook persisted the 200000 value as a "proven" window for the session's lifetime, and the agent itself confidently told the user the session had a 200k window (it didn't). Any consumer below the crossing cannot distinguish a genuine 200k session from a 1M session being reported at the floor — the field carries no information at exactly the value it defaults to.

Possibly related: the model.id in the payload churned across captures (claude-opus-5 — not a public model ID — then claude-fable-5), suggesting the window may be resolved from a model label that isn't settled early in bridge sessions.

Suggested fix shape: populate context_window_size from the session's actually-provisioned window at launch, or omit/null the field when unknown rather than defaulting to 200000 — a wrong-but-plausible default is strictly worse for consumers than an absent value.

bcherny collaborator · 14 days ago

I tried to reproduce this on Linux with a statusline command that dumps the JSON it receives, on both the current release (2.1.233) and the version you reported (2.1.198), using a first-party subscription login.

In both versions, starting a fresh session with --model 'claude-fable-5[1m]' (and also opus[1m]) reported context_window.context_window_size: 1000000 in the statusline JSON, used_percentage computed against 1M (e.g. 4% at ~41K tokens), and /context showed an …/1m tokens denominator. So I couldn't reproduce a 200K denominator, even on 2.1.198.

A fix that matches your symptom shipped in 2.1.208: the context window could briefly reset to 200K after the CLI auto-updated, causing a false "100% context used" on resumed long-context sessions (changelog). Could you retest on the latest version and, if it still happens, share:

  1. Your plan type (Pro/Max/Team/Enterprise), and whether the session had been resumed or auto-updated mid-session
  2. Whether CLAUDE_CODE_DISABLE_1M_CONTEXT or a custom ANTHROPIC_BASE_URL is set (including via managed/enterprise settings)
  3. The context_window object from a fresh session's first turn on the latest version

🤖 Generated with Claude Code

github-actions[bot] · 14 days ago

We weren't able to reproduce this. Could you provide steps to trigger the issue — what you ran, what happened, and what you expected? This issue will be closed automatically if there's no activity within 7 days.

Showing cached comments. Read the full discussion on GitHub ↗