[BUG] VS Code extension: effort selector offers "Max", shows it as selected, and silently runs at a lower level

Status Open
Reported on v2.1.220
Maintainer reply None cached
Activity 2 comments · opened Jul 30, 2026

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

  1. In the extension, open the effort selector and choose Max. It shows Max as selected; ~/.claude/settings.json gets "effortLevel": "max".
  2. In that session or any later one, have Claude run echo $CLAUDE_EFFORT via Bash — that's the turn's resolved effort, i.e. the effect rather than the config.
  3. Expected: max. Actual: high (the model's default_effort), with the selector still displaying Max.
  4. 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

  1. Make max persistable (add it to the effortLevel enum) — #35904's ask; it would make the display truthful.
  2. If max is session-only by design, don't offer it as a persistable choice in the selector, or surface the warning string the CLI already has.
  3. Either way: replace .catch(void 0) on effortLevel with 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).

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗