anthropics / anthropics/claude-code
[BUG] opusplan silently stops upgrading to Opus in plan mode once conversation context exceeds 200k tokens
- Dominant language
- Python
- Stars
- 145k
- Forks
- 23.1k
- PR merge metrics
- PR metrics pending
Description
### Preflight Checklist
- [x] I have searched [existing issues](https://github.com/anthropics/claude-code/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug) and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
### What's Wrong?
This is a recurrence of #65512 (reported, fixed in 2.1.172, reopened-in-spirit by a later comment
on that same closed/locked issue reporting it back on 2.1.216). Filing new since #65512 is locked.
With model set to "opusplan", plan mode is supposed to run on Opus and non-plan/auto mode on
Sonnet. This works correctly at the start of a session. Once the conversation's context usage
(input + cache_creation + cache_read tokens) passes ~200k tokens, plan mode silently stops
upgrading to Opus and keeps using Sonnet instead — with no warning anywhere (statusline, CLI
output) — even though the session's context_window_size is reported as 1000000.
### What Should Happen?
Per the accepted fix for #65512: the plain "opusplan" preset should auto-compact context to stay
under ~200k specifically so the plan-mode Opus guard never trips, while "opusplan[1m]" should keep
both modes on the 1M window. On 2.1.274, this is not what happens: context accumulates past 200k
without compaction, and plan mode downgrades to Sonnet silently, no notice shown.
### Error Messages/Logs
```shell
Statusline stdin payload captured right after switching into plan mode (permissionMode: "plan"
confirmed in the session transcript immediately before this render):
{"exceeds_200k_tokens": true,
"context_window": {"context_window_size": 1000000,
"current_usage": {"cache_read_input_tokens": 315538, "cache_creation_input_tokens": 847}},
"model": {"id": "claude-sonnet-5", "display_name": "Sonnet 5"}}
No auto-compaction event occurred anywhere in the transcript despite context exceeding 200k well
before this point. Transcript also shows no "You are powered by the model named Opus" system
reminder around this render, while an earlier plan-mode switch in the same session (context still
under 200k) did produce that reminder together with a real Opus turn.
```
### Steps to Reproduce
1. Start a session with model set to "opusplan" (~/.claude/settings.json: "model": "opusplan").
2. Toggle between plan mode and auto/default a couple of times before sending any prompt — the
active model switches correctly each time.
3. Work normally until the conversation's token usage (input + cache_creation + cache_read) passes
~200k tokens — this happens naturally within one moderately long session, with no compaction
observed to intervene beforehand.
4. Switch back into plan mode.
5. Observe: the model used for the next turn is still Sonnet, not Opus, with no warning shown.
### Claude Model
Not sure / Multiple models
### Is this a regression?
Yes, this worked in a previous version
### Last Working Version
2.1.172
### Claude Code Version
2.1.274
### Platform
Anthropic API
### Operating System
macOS
### Terminal/Shell
Terminal.app (macOS)
### Additional Information
See #65512 for the original report, the accepted fix (v2.1.172), and a later comment on the same
(now locked) issue reporting the exact same recurrence on v2.1.216 with a turn-by-turn table
matching this report's shape. This report adds independent confirmation on v2.1.274, ~2 months
later, via statusline payload capture cross-referenced with session transcript permissionMode and
message.model fields — same root cause, still unresolved.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the model setting in ~/.claude/settings.json, then trace the plan-mode switch alongside the statusline stdin payload and session transcript fields described here. Reproduce after context usage exceeds 200k tokens and compare the plain opusplan behavior with opusplan[1m]. Done means plain opusplan compacts before the limit so plan mode uses Opus, while the 1M preset retains its larger window, with an appropriate notice if needed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100