opusplan: exiting plan mode does not switch to Sonnet, stays on Opus for execution
Description
With "model": "opusplan" set in ~/.claude/settings.json, exiting plan mode does not
switch the main loop to Sonnet. It stays on Opus for the entire session, including all
execution turns after the plan is approved.
This looks like a regression/recurrence of #6108 (closed 2025-10-15) and #27183 (opened
2026-02-20, auto-closed as a duplicate of #6108 despite describing the same "100% Opus,
Sonnet quota never consumed" symptom). Filing fresh rather than commenting on either,
since #6108 is stale and this is reproducing on a much newer version.
Reproduction
- Set
"model": "opusplan"at the top level of~/.claude/settings.json(no project-
level model key, no ANTHROPIC_MODEL env var, no --model launch flag).
- Launch
claudewith no flags./modelcorrectly reportsopusplan. - Enter plan mode (Shift+Tab or the plan-mode tool). Confirmed via transcript: turns in
plan mode record "message":{"model":"claude-opus-5",...} — correct so far.
- Exit plan mode (approve the plan). The session's JSONL records the mode transition
({"type":"mode","mode":"normal"} / {"type":"permission-mode","permissionMode":"default"})
immediately after the ExitPlanMode tool call.
- Continue in execution mode. Every subsequent turn's
message.modelfield still reads
claude-opus-5. Sonnet never appears.
I additionally checked 5 prior sessions in the same project, spanning two days before
this test — all recorded claude-opus-5 exclusively across every turn, no claude- anywhere in any of them.
sonnet-5
Expected behavior
Per https://code.claude.com/docs/en/model-config.md, opusplan should use Opus in plan
mode and switch to Sonnet for the execution portion after exiting plan mode.
Actual behavior
Opus runs continuously — plan mode and execution alike. The Sonnet leg of opusplan
never activates, so every turn bills as Opus regardless of mode.
Environment
- Claude Code version: 2.1.236
- OS: macOS (Darwin 25.6.0)
- Model alias:
opusplan, resolving toclaude-opus-5/claude-sonnet-5
Additional note
Plan mode itself writes no distinguishing record to the session transcript (no field
anywhere is set to the literal value plan) — only mode: normal and permission-mode: appear before/after, cycling on unrelated permission-mode changes too. This made
auto
the bug harder to diagnose: the transcript's model field is currently the only reliable
way to audit which model actually served the request, e.g. via the pattern above.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗