Mid-session model switch not applied — UI shows the new model, session keeps running the previous one (+ silent budget loss)

Status Open
Maintainer reply None cached
Activity 3 comments · opened Jul 3, 2026

Preflight Checklist

  • [x] I have searched existing issues 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?

Environment

  • Claude Code v2.1.191, VS Code extension (model-switch also observed earlier in the Claude desktop app)
  • macOS (Darwin 25.5.0)
  • Models: Fable 5 (claude-fable-5) → Opus 4.8 (claude-opus-4-8), switched with the [1m] context flag

Summary
Switching the model mid-session does not reliably take effect. The client UI (status line / model indicator) updates to the newly selected model, but the session continues generating on the previously active model. There is no reliable in-session way to confirm which model is actually serving requests, so the discrepancy is silent — and it spends the wrong model's budget without the user knowing.

Observed

  • UI reflects model B (Opus) everywhere.
  • Session identity/behavior still corresponds to model A (Fable) — the system identity remained Fable after the switch (context not regenerated to B).
  • No authoritative in-session confirmation of the active model: /status is NOT a recognized command, and model self-report is unreliable. Neither user nor assistant could determine the truth from inside the session.
  • Previously reproduced in the Claude desktop app: switched there and the session kept running the prior model.

Impact

  • Real, quantifiable budget loss — the core complaint. The switch's whole purpose was to move rote work OFF the scarce higher-tier (Fable) budget onto Opus. Because the switch didn't reliably take (or couldn't be confirmed), a considerable portion of the user's limited weekly Fable budget was consumed by work explicitly intended for Opus. That budget is capped and expires at week's end — burned budget is unrecoverable and directly reduces the high-value work still possible before the cap resets.
  • Silent wrong-model spend, with no in-session indication.
  • No way to verify, so the loss compounds — the user can't tell whether a switch worked without checking the billing dashboard afterward, by which point it's already spent. A user actively trying to conserve a scarce budget is exactly who this harms most.

Suggested fixes

  1. Make a mid-session /model switch fully re-initialize the model context (identity/system prompt included), not just the UI label.
  2. Add an authoritative model check (/status, or /model with no args printing the currently active model) reflecting the real inference model, not the UI selection.
  3. If a mid-session switch requires a fresh session, have the UI say so explicitly.

What Should Happen?

Expected

  • The switch takes effect next turn (inference AND identity move to B), or
  • if a mid-session switch can't be fully applied, the client says a restart is required — instead of showing B while continuing on A.

Error Messages/Logs

Steps to Reproduce

  1. Start a session on model A (here: Fable 5).
  2. Mid-session, switch to model B via /model — e.g. /model opus. Local output confirmed: Set model to claude-opus-4-8[1m].
  3. The model indicator updates to B (Opus) everywhere.
  4. Continue the conversation.

Claude Model

Not sure / Multiple models

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

Claude Code v2.1.191

Platform

Other

Operating System

macOS

Terminal/Shell

VS Code integrated terminal

Additional Information

_No response_

View original on GitHub ↗

3 Comments

zbest1 · 3 months ago

Adding to this ticket as a second affected user — same bug in a different environment (iTerm2, not VS Code), with a full transcript trace that pins down the mechanism.

In my case the root cause is more specific than "mid-session switch not applied": the session launched on Fable and could never be moved off it. A changed default applies only to brand-new sessions; returning to / resuming an existing session silently keeps its launch model while /model falsely confirms the switch.

Environment: macOS Darwin 25.5.0; Claude Code v2.1.198–2.1.201; iTerm2; Fable 5 → Opus 4.8 [1m].

Timeline:

  • 07-02 — Started a session on claude-fable-5[1m].
  • 07-03 — /model → Opus 4.8; output said "set model to Opus 4.8 (1M context) and saved as your default for new sessions." Every session I created from 07-03 onward opened on Opus — so the default took. This pre-existing session did not adopt it.
  • 07-06 — Re-ran /model to double-check: the picker and status line both showed Opus 4.8 with a green checkmark — yet it kept generating on Fable.

Why it stayed invisible: every prior model/effort switch I'd made applied to the live session immediately, so nothing signaled this one hadn't — and there's no reliable in-session way to see the true model. I only noticed because my Fable usage was visibly draining at claude.ai/settings/usage, then confirmed by tracing message.model across two parallel sessions.

Transcript proof (message.model per assistant turn — the only ground truth): 478/478 assistant turns claude-fable-5, zero Opus, launch 07-02 → 07-06, every one while the picker and status line reported Opus 4.8. ≈915K Fable output tokens (+≈131K input, ≈11M cache-write, ≈151M cache-read), spent on routine work I'd explicitly switched to Opus to keep off Fable.

Impact: Fable is my rationed, expensive tier; this one session's silent ≈915K-token burn helped exhaust the allowance — invisible because every UI surface showed Opus.

Asks:

  1. A resumed / returned-to session must adopt the current model (or changed default) — or state explicitly that it's still on its launch model.
  2. The status line and /model picker must reflect the model actually serving the session; never show a green "kept"/selected check for a model it isn't on.
  3. Warn when an expensive/rationed model keeps serving after a different one is selected.

Same root cause in related reports: #73879, #70058, #49541, #73488.

ThatDragonOverThere · 1 month ago

Adding a corroborating instance of the exact mechanism described in this issue — switching away from Fable in the app's own model selector doesn't actually move the running work off it.

Confirmed at the config level, which makes this a bit sharper than a UI-only report: I checked the global settings file directly, and the model field had genuinely changed from the Fable model identifier to a non-Fable one — so the app-side write of the new selection really happened, it's not a display glitch. Despite that, the session kept consuming Fable-tier usage rather than the newly-selected model.

This lines up exactly with the mechanism another commenter described here — the switch "takes" at the config/UI level, but an already-running session keeps billing/running the previous model regardless, and only a session started fresh under the new default actually routes correctly. Filing this as independent corroboration since it reproduces cleanly and matches that description precisely rather than being adjacent/similar.

ThatDragonOverThere · 28 days ago

Still happening on 2.1.270 — now on the desktop app's own model selector, and the billing consequence is the whole problem

Another instance of exactly this, fresh today, on a current build. Adding it because the thread is open and because the framing in the title — "+ silent budget loss" — is, in practice, the entire bug. Everything else is cosmetic next to it.

What happened: changed the model in the Claude app's model selector, deliberately, to move work off the expensive tier. The selector showed the new model. Already-running desktop sessions kept executing — and kept billing — as the previously-selected, more expensive tier. No warning that the change applies only to sessions started afterward. No indication inside the running session that it was still on the old model. The only feedback that the change hadn't taken arrived later, as consumed allowance.

Please don't file this under "running sessions keep their boot model." That behavior is understood, and for the CLI it's documented. That is not what is being reported. The defect is the combination:

  1. The product accepts the tier change.
  2. The product displays it as applied.
  3. The product continues charging the previous rate.

A confirmation that doesn't correspond to what you're billed for isn't a UI nit. It's the control surface lying about the thing it exists to control.

The fairness problem, stated plainly

The only reason anyone switches tiers mid-flight is to stop spending a scarce, capped allowance. That is the entire function of the control.

So when the switch silently doesn't apply:

  • The action taken specifically to stop spending the expensive tier does not stop spending the expensive tier.
  • The user is charged the premium rate for work they explicitly redirected away from that rate.
  • They are charged it on the strength of a confirmation the product itself displayed.
  • The allowance is capped and does not come back.

A tier selector that cannot be relied on to take effect is not a usage control. It is the appearance of one, and users are budgeting against it. Being metered for a choice you visibly made and the product visibly accepted is not a defensible outcome, and "it only applies to new sessions" is not a fix — it's a description of the trap.

If the change genuinely cannot apply to a running session, then the honest behaviors are: say so at the moment of selection, refuse the selection, or offer to restart the session. Accepting it silently and charging the old rate is the one option that costs the user money for the product's limitation.

Prior instances, same mechanism

This is the third time this shape has been documented locally:

  1. This issue's original report, plus the follow-up comment here establishing that a changed default takes effect only on a brand-new session.
  2. A firsthand reproduction at the config-file level: the global config's model field genuinely changed to the newly-selected model — the write happened — and the running session kept consuming the previous tier regardless. (Posted to this thread previously.)
  3. This one, on the desktop app's selector — notably the surface a non-CLI user would treat as authoritative, and the one with no --model escape hatch to fall back on.

One adjacent thing that may be a clue

A model value is persisted in at least three separate layers — project settings, user settings, and the global config file. On a current machine those three hold three different values simultaneously, and the global config carries several model fields with mixed values of its own.

Whatever the intended precedence is, the practical result is that "which model is this session actually running, and which one am I being charged for?" is not answerable from any single location — by the user, and seemingly by the product. That seems worth looking at alongside the switch itself.

Ask

  • Make the selector's confirmation mean the thing it appears to mean, or state clearly at selection time that it won't apply to this session.
  • Surface the effective model of a running session somewhere the user can see it, distinct from the selected model.
  • Treat the billing side as the priority: a tier change that is accepted and displayed should never be followed by charges at the old tier.

Version: 2.1.270. Happy to provide anything further that would help reproduce.