[BUG] VS Code extension: effort selector offers "Max", shows it as selected, and silently runs at a lower level
Bug description
The VS Code extension's effort selector offers Max, displays it as selected once picked, and the session then runs lower with no warning anywhere — in my case at high, two levels below what the selector showed.
The root cause is the known schema issue (#35904): the selector persists the choice by writing effortLevel to settings.json, whose schema is enum(["low","medium","high","xhigh"]).optional().catch(void 0), so max is dropped silently and the session falls back to the model's default_effort. This report is the display half, which #35904 doesn't cover — that one is area:cli and its repro is about persistence, whereas here a GUI keeps affirming a level that isn't running.
What makes it worse: the CLI already contains the exact warning for this situation — "max is session-scoped and won't reach the remote process. Use low, medium, high, or xhigh instead." — and the channel the extension uses never surfaces it. Same class as the /model success banner reported in #35904.
Environment
Claude Code VS Code extension 2.1.220 (linux-x64), CLI 2.1.220 (latest published at time of writing), Kubuntu 24.04, model claude-opus-5.
Steps to reproduce
- In the extension, open the effort selector and choose
Max. It showsMaxas selected;~/.claude/settings.jsongets"effortLevel": "max". - In that session or any later one, have Claude run
echo $CLAUDE_EFFORTvia Bash — that's the turn's resolved effort, i.e. the effect rather than the config. - Expected:
max. Actual:high(the model'sdefault_effort), with the selector still displayingMax. - For contrast, the same session opened from the Claude Android app via Remote Control shows the real level. Two official surfaces disagree about one session: the extension reports the saved value, the mobile app the effective one.
Why this isn't cosmetic
A silent discrepancy makes you believe you requested more reasoning than you got, and you only find out by instrumenting the session. It bit here in a case with consequences: a critical review was explicitly requested at Max effort because the previous pass hadn't been thorough enough, and that session ran at high end to end with nothing indicating it.
Suggested fix, in order of preference
- Make
maxpersistable (add it to theeffortLevelenum) — #35904's ask; it would make the display truthful. - If
maxis session-only by design, don't offer it as a persistable choice in the selector, or surface the warning string the CLI already has. - Either way: replace
.catch(void 0)oneffortLevelwith a startup validation warning, so an unhonorable value is never dropped in silence.
Workaround
The extension exposes claudeCode.environmentVariables (machine scope, array of {name, value}), injected straight into the spawned claude process env, so CLAUDE_CODE_EFFORT_LEVEL=max there gives real max scoped to the extension only — without touching the desktop session environment or the CLI in a terminal. Note it acts as an override rather than a floor: it wins over a lower per-session choice, leaving the selector decorative (see also #80959, on env-vs-flag precedence being undocumented).
Related
#35904 (open; root cause), #43322 (same symptom, closed by the inactivity bot), #80959 (settings precedence docs omit environment variables).
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗