opusplan plan mode skips Max-plan 1M auto-upgrade
opusplan plan mode skips Max-plan 1M auto-upgrade
Version: claude 2.1.112 (also observed on 2.1.111)
Summary
The docs at https://code.claude.com/docs/en/model-config state: "On Max, Team, and Enterprise plans, Opus is automatically upgraded to 1M context with no additional configuration." This upgrade does not apply to opusplan plan mode.
Reproduction
- First-party Anthropic API user on a Max plan
~/.claude/settings.jsonhas"model": "opusplan"and noANTHROPIC_DEFAULT_OPUS_MODELset- Open a new Claude Code session and enter plan mode (Shift+Tab)
- Observed: the resolved model is
claude-opus-4-7(200K context) - Expected: the resolved model is
claude-opus-4-7[1m](1M context)
Observable signals: the startup header suffix (1M context) is absent; /status shows claude-opus-4-7 without [1m].
Note: the "Welcome to Opus 4.7 xhigh!" welcome banner is a hardcoded string and is not a reliable signal — it does not reflect whether [1m] is active.
Code trace (2.1.112)
The opusplan router is om({permissionMode, mainLoopModel, exceeds200kTokens}). The plan-mode branch (verbatim from the binary):
if (ub() === "opusplan" && _ === "plan" && !K) return bh()
bh() is the opus model resolver. It returns ANTHROPIC_DEFAULT_OPUS_MODEL if set; otherwise returns the built-in claude-opus-4-7 constant. No [1m] is appended on either path.
The Max auto-upgrade function has the body pattern:
if (SD() && !pJ(H) && /opus-4-[67]/.test(H)) return H + "[1m]"
(SD() checks first-party Max eligibility; pJ(H) checks whether [1m] is already present.)
Grepping for call sites of this function in the 2.1.112 binary finds exactly 2 call sites, both on the subagent-resolution path. om() never calls it.
The main-loop default getter (dG()) does route through the Max auto-upgrade, but opusplan plan mode does not use dG() — it uses om() directly.
Result: SD() === true (first-party Max user), but plan mode still resolves to 200K because om() returns bh() without passing through the auto-upgrade wrapper.
Expected behavior
om() must wrap its opus return through the Max auto-upgrade function, consistent with how the /model opus, /model opus[1m], and subagent paths handle it.
Workaround
Set ANTHROPIC_DEFAULT_OPUS_MODEL="claude-opus-4-7[1m]" in ~/.claude/settings.json:
"env": {
"ANTHROPIC_DEFAULT_OPUS_MODEL": "claude-opus-4-7[1m]"
}
bh() returns the env var verbatim; om() in plan mode then yields claude-opus-4-7[1m]. The subagent auto-upgrade wrapper no-ops (because pJ("...[1m]") is true), so no double [1m] occurs.
Trade-off: this loses auto-latest — the env var must be manually bumped when a new Opus version ships.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗