effortLevel setting doesn't support "max" value
Status Fixed / completed
Maintainer reply None cached
Workaround ✓ Mentioned in thread ↓
Activity 9 comments · opened Mar 18, 2026 · closed Aug 19, 2026
Bug
/effort max works as a session-only command and sets effort to "Maximum capability with deepest reasoning (Opus 4.6 only)", but this value cannot be persisted in settings.json.
The effortLevel field in the settings schema only allows "low", "medium", "high":
"effortLevel": {
"description": "Persisted effort level for supported models.",
"type": "string",
"enum": ["low", "medium", "high"]
}
Setting "effortLevel": "max" in ~/.claude/settings.json is silently ignored (falls back to default).
Expected behavior
"max" should be a valid value in the effortLevel enum so it can be persisted across sessions, just like the other effort levels.
Steps to reproduce
- Run
/effort max— works, confirms "Set effort level to max (this session only)" - Add
"effortLevel": "max"to~/.claude/settings.json - Restart Claude Code
- Run
/effort— shows "high", not "max"
Environment
- Windows 11 Pro
- Claude Code CLI
- Model: Opus 4.6
Showing cached comments. Read the full discussion on GitHub ↗
8 Comments
Same issue here. Windows 11 + PowerShell, v2.1.79. Setting "effortLevel": "max" in ~/.claude/settings.json is silently ignored, falls back to medium. /effort max works at runtime but doesn't persist.
Can confirm —
"effortLevel": "max"in settings.json is silently ignored because the schema enum is["low", "medium", "high"]. No warning, no error, just falls back to default.I read this field via
--slurpfilein claude-lens andmaxnever appears in the statusline output, even when set — because the fallback happens before any external script reads it.+1 on adding
maxto the enum. The silent fallback is the worst part — at minimum it should log a validation warning on startup.The schema currently only accepts
"low","medium","high"—"max"is only available as a runtime command via/effort maxand doesn't persist across sessions.Workaround — SessionStart hook to auto-remind:
This sets the highest persistent level (
high) and reminds you at session start that/effort maxis available for the current session.Alternative — CLAUDE.md instruction:
Add to your project's
CLAUDE.md:This doesn't change the API-level effort parameter, but it instructs the model to use thorough reasoning regardless of the effort setting. Combined with
"effortLevel": "high", this gets close to max behavior.The silent fallback with no warning is the worst part of this bug — at minimum the settings parser should warn when an unsupported value is provided.
Ive found a temporary workaround, put this to your settings.json:
Confirming the same behaviour on Linux (Ubuntu, Claude Code CLI, Opus 4.6).
"effortLevel": "max"in~/.claude/settings.jsonis silently ignored. Every new session starts atauto (currently medium)./effort maxworks session-only.Additionally — permissions defined in the same
settings.jsonalso appear to not be fully applied on session start, which suggests the silent-ignore behaviour may extend beyond justeffortLevel. Possibly related: #30519, #36192, #36168.Workaround:
/effort maxat session start.Still present on Claude Code 2.1.112 / macOS 14.1.2 (Darwin 23.1.0), Opus 4.7 (1M context).
The schema has since been updated to accept
xhigh(I currently have"effortLevel": "xhigh"persisted), butmaxis still silently dropped.Repro via
/modelinstead of/effort:/model, select max effort. Banner prints:Set model to Opus 4.7 (1M context) (default) with max effort✓``
bash
``python3 -c "import json; print(json.load(open('/Users/me/.claude/settings.json'))['effortLevel'])"
max. Actual: prior value (in my casexhigh).Side effects:
effortLevelfromsettings.jsoncan never render amaxstyling (see also #41985, #45805 asking foreffortLevelin statusline stdin)./modelconfirmation message is misleading because it claims persistence succeeded.Suggested fix: add
"max"(and"xhigh"if missing) to theeffortLevelenum in the settings schema, gated on the user's plan if necessary (per #33937 for Max plan scoping).small update for anyone landing here — the CLI flag path on v2.1.116 now explicitly accepts
maxin the help text:settings.json
effortLevelstill silently falls back toxhighon a fresh restart (the schema enum hasn't been updated to includemax), so this issue's core problem is still reproducible. but the CLI flag is now documented, which gives a clean launch-time workaround that doesn't rely on env var inheritance quirks:combined with
"effortLevel": "xhigh"in settings.json as a valid baseline (won't silently fail on startup, and the alias overrides it per-session), this gives a stable max-effort setup until the schema is updated.also confirming @relanderolli's env var approach (
CLAUDE_CODE_EFFORT_LEVEL=maxunderenv) works alongside this — but the CLI flag is now first-class in--help, so it's the most discoverable path forward for new users hitting this.real fix request stands: add
maxto theeffortLevelenum in the settings schema. the inconsistency between "CLI accepts it, settings.json rejects it" is the confusing part, and a silent fallback with no validation warning on startup is the worst UX.Still reproducible on 2.1.220 (currently the latest published version), Linux,
claude-opus-5, via the VS Code extension. Two findings that I think matter for the fix, since neither is visible from outside.1. The fallback value isn't a constant — it's the model's default, which is why this thread reports four different ones. Comments here variously report
medium,auto (currently medium),xhigh; I measuredhigh. There are two different parsers. Startup resolution is, in effect:gWaccepts the full canonical list (low|medium|high|xhigh|max, plus integers and themedalias);Q6ereturns onlylow|medium|high|xhigh, andundefinedfor anything else — which is what the.catch(void 0)then swallows. So the asymmetry isn't only that the enum lacksmax: the flag channel and the settings channel validate with different functions. With nothing resolved, the per-turn resolver falls back toait(model)=default_effort ?? "high", so the level you land on depends on the model, not on a fixed app default.2. Two more silent downgrades that would survive the proposed one-line fix. Same per-turn resolver:
if (s === "max" && !eqe(model)) s = "high"(modelmax_effortcapability gate), then a clamp to the organization'smaxEffortLevel. Both silent, both producing the identical symptom by a different cause — there's even a prepared "exceeds your organization's limit" message that doesn't fire on this path. Neither gate is biting on my account (the--effort maxflag path passes both and does run at max), but it means addingmaxto the enum alone wouldn't guarantee the symptom disappears for everyone landing here. What closes the whole class is a startup validation warning wheneffortLevelholds a value that can't be honored, instead of.catch(void 0).Worth noting: the schema has been edited since this was filed —
xhighwas added,maxwasn't. Not a forgotten field.Verification method, in case it helps triage: reading
settings.jsonback can't answer this, since the bug is precisely that config and effect disagree.echo $CLAUDE_EFFORTfrom inside a session does — the CLI injects the turn's resolved effort into tool subprocesses.Identifier names above are from the 2.1.220 bundle and get remangled per build; the control flow is the stable part, not the names.