[BUG] Settings effortLevel "max" is silently downgraded when user interacts with effort selection UI

Status Open
Reported on v2.1.68
Maintainer reply None cached
Activity 10 comments · opened Mar 4, 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?

When effortLevel is set to "max" in settings (e.g., ~/.claude/settings.json), the effort callout dialog shown on session start and the /model command only offer three options: low, medium, and high. Since max is not among the choices, selecting any option (typically high) silently overwrites the user's max setting for the remainder of the session.

This is despite the fact that:

  • The API documentation defines effort as "low" | "medium" | "high" | "max" (four values)
  • The Effort documentation explicitly describes max as "Absolute maximum capability with no constraints on token spending" (Opus 4.6 only)
  • claude --help shows --effort <level> with only (low, medium, high), omitting max
  • The Claude Code documentation also lists only three levels

So the API formally supports max, and the settings file accepts it without error, but there is no way to select or preserve it through the UI.

What Should Happen?

  1. If the user has set effortLevel: "max" in settings, the effort selection UI should either include max as an option, or not prompt the user to re-select effort at all (respecting the existing setting).
  2. claude --help and the Claude Code documentation should reflect the full set of valid values including max.
  3. At minimum, the UI should not silently downgrade a user's explicitly configured effort level.

Error Messages/Logs

_No error messages — the downgrade is silent._

Steps to Reproduce

  1. Set effortLevel to "max" in ~/.claude/settings.json:

``json
{ "effortLevel": "max" }
``

  1. Start a new session with claude
  2. Observe the effort callout dialog — only low, medium (recommended), and high are offered
  3. Select high (the closest available option to max)
  4. The session now runs at high effort instead of the configured max
  5. Similarly, running /model and adjusting effort only offers the same three options

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.68

Platform

Anthropic API

Operating System

Ubuntu/Debian Linux

Terminal/Shell

iTerm2

Additional Information

Related issues:

  • #23606 — Feature request to add max effort to the UI (different angle: FR vs. this bug where existing settings are overwritten)
  • #23604 — CLAUDE_CODE_EFFORT_LEVEL environment variable not reflected in /model UI
  • #26950 — Effort level cannot be inspected or reliably controlled

Key distinction from #23606: This issue is specifically about settings being silently overwritten. Even if max is intentionally excluded from the UI, the current behavior should not force users to re-select effort and lose their configured value.

✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)

View original on GitHub ↗

10 Comments

antoniopresto · 5 months ago

Same. We added it here to show actual settings:

# settings.json
  "statusLine": {
    "type": "command",
    "command": "bash ~/.claude/statusline-command.sh"
  },
# statusline-command.sh

#!/usr/bin/env bash
input=$(cat)

model_id=$(printf '%s' "$input" | jq -r '.model.id // empty')
model_display=$(printf '%s' "$input" | jq -r '.model.display_name // empty')

if [ -n "$model_id" ]; then
  case "$model_id" in
    *opus*)   model_label="Opus"   ;;
    *sonnet*) model_label="Sonnet" ;;
    *haiku*)  model_label="Haiku"  ;;
    *)        model_label="${model_display:-unknown}" ;;
  esac
else
  model_label="${model_display:-unknown}"
fi

effort=$(jq -r '.effortLevel // empty' ~/.claude/settings.json 2>/dev/null)
effort=${effort:-high}
if [ "$effort" != "high" ]; then
  effort_part=$' | \033[0;31meffort: '"${effort}"$'\033[0m'
else
  effort_part=" | effort: ${effort}"
fi

used_pct=$(printf '%s' "$input" | jq -r '.context_window.used_percentage // empty')

if [ -n "$used_pct" ]; then
  used_int=$(printf '%.0f' "$used_pct" 2>/dev/null || echo "$used_pct")

  if [ "$used_int" -ge 80 ] 2>/dev/null; then
    ctx_part=$' | \033[0;31m'"${used_int}% ctx"$'\033[0m'
  elif [ "$used_int" -ge 50 ] 2>/dev/null; then
    ctx_part=$' | \033[0;33m'"${used_int}% ctx"$'\033[0m'
  else
    ctx_part=$' | \033[0;32m'"${used_int}% ctx"$'\033[0m'
  fi
else
  ctx_part=""
fi

printf '%b' "[${model_label}]${effort_part}${ctx_part}"
oronbz · 5 months ago

For me max is still showing in the UI, although I'm in 2.1.72, anyone knows why?

<img width="1216" height="828" alt="Image" src="https://github.com/user-attachments/assets/5a90989d-ff49-47ba-a6cb-16a9b32b6ec3" />
<img width="1259" height="377" alt="Image" src="https://github.com/user-attachments/assets/031e33ef-46f7-4dfb-8ca1-5f85f342aba8" />

JanChec · 5 months ago

For me (2.1.72), I'm starting with "max" from my settings.json via both CLAUDE_CODE_EFFORT_LEVEL and effortLevel, and it shows "max" in the footer, but the /model selection shows "medium" as the current one. At the same time, the welcome text doesn't show effort, simply the model: "Opus 4.6" - like in the screenshot above. Using only one of the variables doesn't fix that.

Workaround: claude --effort max - then it shows the effort in the welcome text, in the footer, and as the selected effort in /model.

scm-aiml · 5 months ago

If I try ‘—effort max’ it actually says only low medium high, but if i override in settings.json it works.

jonlepage · 5 months ago

Environment:

  • Claude Code VS Code extension (latest)
  • Windows 10 Pro
  • Model: Claude Opus 4.6 (1M context)
  • Subscription: Max

Issue:
No persistence method works for effortLevel: "max" in the VS Code extension. Every new chat resets to medium.

What I tried (all failed):

| Method | Result |
|--------|--------|
| ~/.claude/settings.json"effortLevel": "max" | Resets to medium on new chat |
| ~/.bashrcexport CLAUDE_CODE_EFFORT_LEVEL=max | Not picked up by VS Code extension |
| Windows user environment variable CLAUDE_CODE_EFFORT_LEVEL=max | Not picked up by VS Code extension |

Expected behavior:
Setting effortLevel to max in settings.json (or via env var) should persist across sessions and new chats in the VS Code extension, just like medium or high do.

Actual behavior:
Every new chat starts at medium regardless of configuration. I have to manually switch to max every single time, which is tedious and easy to forget.

seanmartinsmith · 5 months ago

wrote up a cross-reference of all the related effort level issues in #40093 - there are at least 5 open issues about the same root cause. tl;dr: "max" was half-removed in v2.1.72 (changelog said 'simplified to low/medium/high') but it still exists in some code paths. banner reads the raw value and shows 'max', but runtime falls back to medium/high depending on the path.

workaround: use "high" not "max" in settings.json or env var. it's the highest value consistently respected across all code paths.

related: #33937, #33542, #39015, #40093, #26950

vksadarangani · 5 months ago

I'm experiencing this issue on Claude Code in desktop. This is related to issue #40095 that was recently fixed, and they feel like two sides of the same coin:

  • #40095: Desktop app silently switched model from Opus to Sonnet via an auto-triggered /model command — no user action involved
  • #30726 (this issue): Effort level silently reverts to medium when interacting with the UI

Both cases involve user-configured settings being quietly overwritten without any warning or error. The user has no indication anything changed unless they happen to notice.

@amorriscode — you helped me with the model revert bug in #40095. Given how similar the pattern is here (silent setting revert, no user action, no warning), I suspect these might share a common root cause in how the UI persists and restores settings state. Would appreciate your input on this one as well. Thank you.

alicelovescake · 4 months ago
I'm experiencing this issue on Claude Code in desktop. This is related to issue #40095 that was recently fixed, and they feel like two sides of the same coin: [[BUG] Desktop app automatically switches model from Opus to Sonnet via /model command (Max subscription) #40095](https://github.com/anthropics/claude-code/issues/40095): Desktop app silently switched model from Opus to Sonnet via an auto-triggered /model command — no user action involved [[BUG] Settings effortLevel "max" is silently downgraded when user interacts with effort selection UI #30726](https://github.com/anthropics/claude-code/issues/30726) (this issue): Effort level silently reverts to medium when interacting with the UI Both cases involve user-configured settings being quietly overwritten without any warning or error. The user has no indication anything changed unless they happen to notice. @amorriscode — you helped me with the model revert bug in #40095. Given how similar the pattern is here (silent setting revert, no user action, no warning), I suspect these might share a common root cause in how the UI persists and restores settings state. Would appreciate your input on this one as well. Thank you.

@vksadarangani I just deployed a fix for this on desktop, can you check again to see if it works correctly? appreciate the report!

vksadarangani · 4 months ago
> I'm experiencing this issue on Claude Code in desktop. This is related to issue #40095 that was recently fixed, and they feel like two sides of the same coin: > > [[BUG] Desktop app automatically switches model from Opus to Sonnet via /model command (Max subscription) #40095](https://github.com/anthropics/claude-code/issues/40095): Desktop app silently switched model from Opus to Sonnet via an auto-triggered /model command — no user action involved > [[BUG] Settings effortLevel "max" is silently downgraded when user interacts with effort selection UI #30726](https://github.com/anthropics/claude-code/issues/30726) (this issue): Effort level silently reverts to medium when interacting with the UI > > Both cases involve user-configured settings being quietly overwritten without any warning or error. The user has no indication anything changed unless they happen to notice. > @amorriscode — you helped me with the model revert bug in #40095. Given how similar the pattern is here (silent setting revert, no user action, no warning), I suspect these might share a common root cause in how the UI persists and restores settings state. Would appreciate your input on this one as well. Thank you. @vksadarangani I just deployed a fix for this on desktop, can you check again to see if it works correctly? appreciate the report!

@alicelovescake - yes appears fixed. Thank you very much.

Oximito · 3 months ago

Additional reproduction: CLI + /model used frequently as workflow

Environment:

  • Claude Code CLI (latest, auto-update enabled)
  • Windows 11 Home
  • Model: claude-sonnet-4-6
  • Subscription: Max plan

Specific scenario not yet documented in this thread:

The /model command overwrites effortLevel in ~/.claude/settings.json every single invocation, regardless of whether the user changes anything. For users who run /model frequently as part of their normal workflow (e.g., to check the current model or switch context), this means:

  1. Session starts with effortLevel: "high" from settings.json
  2. User runs /model to switch models mid-session (routine workflow action)
  3. /model picker shows only low / medium / high — user selects high
  4. settings.json is rewritten — sometimes with medium, sometimes low, depending on which model was selected and what the picker defaulted to
  5. Next session starts at the wrong effort level, silently

Observed in this session:

  • settings.json had "effortLevel": "low" at session start
  • User ran /model (output said "max effort")
  • settings.json was rewritten as "effortLevel": "medium"
  • Discrepancy: display said "max" but file was written as "medium"

This confirms the comment by @seanmartinsmith: the banner/display reads the raw value and shows whatever is stored, but the runtime applies a different (lower) value. So users have no reliable way to know what effort level is actually being applied to API calls.

Additional finding — schema mismatch:
As noted in #43853 (closed as dupe), "max" is not in the settings.json schema enum (["low", "medium", "high"]), so any user who manually sets "effortLevel": "max" in settings.json is silently getting medium/high depending on the code path. This creates a false sense of security — the file says "max", the UI says "max", but the model runs at a lower effort.

Requested fix (agreeing with the analysis in #49076):

Option A (preferred): /model should be session-scoped and never write effortLevel to settings.json. Documented behavior says /model is session-only — the persistence is an undocumented side effect.

Option B: At minimum, add "max" to the schema enum and ensure the UI exposes it as a selectable option so users can make an informed choice.