[Bug] Claude Opus 5 context window size incorrectly reported as 200k instead of 1M tokens
Bug Description
Claude Code v2.1.216 reports context_window_size: 200000 for model claude-opus-5 (a 1M-context model), so the statusline context gauge saturates and /compact appears to do nothing.
The statusline hook receives:
"model": {"id": "claude-opus-5"},
"context_window": {"total_input_tokens": [REDACTED], "context_window_size": 200000, "used_percentage": 90}
"exceeds_200k_tokens": [REDACTED]
179399/200000 = 90%, so the arithmetic is fine — the window constant is wrong.
Evidence it is not an account cap: the SAME session file records main-loop requests of 1,211,454 prompt tokens under claude-opus-4-8 and 573,238 under claude-fable-5. Only claude-opus-5 is treated as 200k, so this looks like a missing model entry and is a regression vs opus-4-8 in the same session.
Impact: sessions get context-pressured and compacted near 200k on a model that carries 1M (~5x under-use of paid context); post-compact the re-injected floor (file-history snapshots, agent listing, invoked-skill text, summary, deferred tool names — ~117k tokens measured here) is already ~59% of the believed window, so /compact never visibly lowers the gauge. It also breaks anything downstream that consumes used_percentage as an occupancy signal.
Environment Info
- Platform: linux
- Terminal: tmux
- Version: 2.1.216
- Feedback ID: 21185b29-66cf-4e01-8767-5538b4006a08
Errors
[]Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
What happened
Claude Code v2.1.216 reports a 200,000-token context window for
claude-opus-5, which has a 1M context window. Everything downstream of that constant is consequently wrong: the statusline context gauge saturates at 100% on long sessions, and/compactappears to have no effect.Evidence
The JSON the statusline command receives on stdin (captured by teeing stdin in the configured statusLine script; unrelated fields removed):
179399 / 200000 = 89.7% → 90, so the percentage math is self-consistent — onlycontext_window_sizeis wrong. The siblingexceeds_200k_tokensfield looks like related 200k-era plumbing.This is not an account or transport limit
Parsing the same session transcript (
~/.claude/projects/<project>/<session>.jsonl), main-loop rows only (isSidechain != true), takingusage.input_tokens + usage.cache_read_input_tokens + usage.cache_creation_input_tokensper request:| model | requests | max prompt tokens observed |
|---|---:|---:|
|
claude-opus-4-8| 15,531 | 1,211,454 ||
claude-fable-5| 2,230 | 573,238 ||
claude-opus-5| 1,996 | 288,460 |The same client, account and session file has carried 1.21M-token prompts under
claude-opus-4-8. Onlyclaude-opus-5is treated as a 200k model, which suggests a missing or stale model entry rather than a deliberate limit — and makes this a regression relative toclaude-opus-4-8.Why
/compactlooks broken (probably the most user-visible symptom)/compactcompresses the conversation but does not reduce what is re-injected afterwards. Measured on one session after the lastcompact_boundary:| re-injected after every compact | ≈ tokens |
|---|---:|
|
file-history-snapshot× 2 | ~34k ||
agent_listing_delta(subagent catalog) | ~17k ||
invoked_skills(full text of every skill invoked earlier in the session) | ~7k || the compaction summary itself | ~5k |
|
deferred_tools_delta(~200 tool names) | ~4k || project memory / instruction files | ~50k |
| floor | ~117k |
Against a true 1M window that floor is ~12%. Against the believed 200k it is ~59% before a single tool call, so one read-heavy turn puts the gauge back above 90% and
/compactnever appears to help.Impact
context_window.used_percentageas an occupancy signal (we use it as an input to an internal preflight check) gets a false "critical" reading permanently.Expected
context_window.used_percentageshould be computed against the effective context window actually in use for the current model. If the 1M window forclaude-opus-5requires a beta flag or tier that this session does not have, the client should still report the effective window it is operating with — and ideally surface which one it picked.Reproduce
claude-opus-5.statusLinecommand that tees its stdin to a file, e.g.input=$(cat); printf '%s' "$input" > /tmp/statusline-input.json..context_window.context_window_sizein that file:200000, with.model.id=claude-opus-5.input_tokens + cache_read_input_tokens + cache_creation_input_tokensper assistant message in the session transcript and compare per-model maxima.Environment
2.1.216claude-opus-5, thinking enabled, efforthigh_WORKAROUND:_ Apparently all you have to do is turn on /usage-credits then the (1M) context loads.
This appears to to apply to Sonnet 5 as well.
Another workaround: append the
[1m]tag to the model tags, even though this shouldn't be necessary.