[BUG] VS Code extension: model/effort picker pill is stale, disconnected from the session's actual resolved settings
Environment: VS Code extension anthropic.claude-code 2.1.278, CLI backend 2.1.263, Linux (WSL2/Debian).
What's wrong: the model/effort pill shown at the bottom of the Claude Code panel (e.g. "Sonnet 5 Medium") does not reflect the settings that are actually resolved and used for the session's real API calls. It appears to be a cached/restored UI value rather than a live read of the settings files on session open.
Repro:
- In a workspace, set
~/.claude/settings.json(user scope) to something like:
``json``
{ "model": "sonnet", "effortLevel": "high", "modelSettings": { "claude-sonnet-5": { "effortLevel": "medium" } } }
- In that workspace's
.claude/settings.local.json(project-local scope, gitignored), set:
``json``
{ "effortLevel": "low" }
- Close and reopen VS Code on the workspace, and open a brand-new Claude Code session/tab (no prior turns).
- Read the pill at the bottom of the panel.
Observed: the pill reads "Sonnet 5 High" — matching neither of the two effort values actually present in the files (medium from the user file's modelSettings.claude-sonnet-5.effortLevel, nor low from the project-local file), and matching only the OLDER, deprecated top-level effortLevel key in the user file, which the picker itself no longer even writes (current picker saves per-model, via modelSettings).
Ground truth, read from the transcript of an actual sent prompt in that same tab: the real API call ran at claude-sonnet-5 / effort low — the project-local file's value, correctly resolved per the documented precedence (project-local > project > user). So:
| source | value |
|---|---|
| picker pill (displayed) | High |
| user file, modelSettings.<model>.effortLevel | Medium |
| project-local file, effortLevel | Low |
| actual API call (verified from the session transcript) | Low |
The actual resolution is correct. The displayed pill is wrong, and matches none of the three candidate sources cleanly — it specifically matches the stale/deprecated top-level key, which is consistent with the pill being restored from some prior cached UI state (extension global/workspace storage?) rather than freshly resolved from the settings files each time a session starts.
Expected: the pill reflects the model/effort the session will actually use (or actually used, once a turn has run), freshly resolved on each new session, exactly as the underlying API call is resolved.
Impact: the pill is the only UI signal for what a session is about to run on. When it disagrees with reality, a user has no way to tell short of grepping the session's transcript JSONL for the model/effort fields on an actual assistant message (which most users cannot easily do). In our case this was caught only because a third-party tool (a UserPromptSubmit hook) independently computed and displayed its own resolution, disagreeing with the pill, which prompted the investigation.
Possibly the same root cause as:
- #91184 (picker disconnected from a session's real model/effort in both read and write directions, for a settings-file-overridden session spawned via the URI handler) — our repro is a plain interactive session (no URI handler, no cross-session bridging), so if it is the same bug, the "picker is not a live read of session state" defect is broader than that issue's spawn-path scoping suggests.
- #77374 (closed as stale, not fixed — "Model picker shows Fable but is actually Opus") — same shape (displayed model/effort disagrees with the real one), on an older version (2.1.208); this report reproduces the same class of defect on a current version (2.1.263 / extension 2.1.278).
Not the same as #90408, which is about actual resolution ignoring project scope — in our repro, actual resolution was correct; only the display was wrong. We're not certain whether all of these share one root cause or are several distinct display/resolution bugs that happen to look similar from the outside; flagging the overlap in case it helps triage rather than asserting it.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗