No overridable default effort level: settings effortLevel is rewritten by /effort, CLAUDE_CODE_EFFORT_LEVEL hard-locks it
Summary
There is no way to pin a default effort level for new sessions that /effort can still override in-session. The two candidate mechanisms each fail in the opposite direction, and neither matches how the model equivalent works:
effortLevelin~/.claude/settings.jsonis too soft:/effortand/modelwrite back into that same file, so it cannot act as a pin.CLAUDE_CODE_EFFORT_LEVELis too hard: it overrides--effortand/effort, so exporting it disables in-session effort changes entirely.
Model configuration has both halves — ANTHROPIC_MODEL (overrides the model setting, still changeable with /model) and ANTHROPIC_DEFAULT_MODEL (applies only when no file sets model). Effort has only the hard-locking form.
Detail
1. The settings key cannot serve as a pin, because in-session commands rewrite it.
With "effortLevel": "high" set in ~/.claude/settings.json, using /effort adds a per-model entry:
{
"effortLevel": "high",
"modelSettings": {
"claude-opus-5": { "effortLevel": "low" }
}
}
Per the settings docs, modelSettings is resolved one model at a time together with effortLevel, so the more specific per-model entry then wins over the top-level key on every subsequent session. The user's intended default is silently superseded by a value written as a side effect of a transient in-session command. (This is the effort-level analogue of #63413, which reports the same write-back behavior for /model.)
2. The env var name does not follow the model convention, and the wrong guess fails silently.
The model variable is ANTHROPIC_MODEL; the effort variable is CLAUDE_CODE_EFFORT_LEVEL. Guessing ANTHROPIC_EFFORT by analogy produces no warning and no effect — an export that appears correct does nothing, with no diagnostic anywhere.
3. Precedence is inverted relative to the model variable.
From the environment variables reference:
--modeland/modeloverrideANTHROPIC_MODEL, whileCLAUDE_CODE_EFFORT_LEVELoverrides--effortand/effort.
So the model variable sets a default the user can still move, while the effort variable is an absolute lock. (#90419 reports the user-facing symptom of this — in-session effort changes silently not applying when the variable is exported.)
Expected behavior
An effort equivalent of ANTHROPIC_DEFAULT_MODEL — for example ANTHROPIC_DEFAULT_EFFORT or CLAUDE_CODE_DEFAULT_EFFORT_LEVEL — that seeds new sessions and is still overridable by --effort and /effort. Alternatively, a settings scope for effortLevel that in-session commands do not write back into, so a file-based pin is possible.
Steps to reproduce
- Set
"effortLevel": "high"in~/.claude/settings.json. - Start a session, run
/effort, pick a different level. - Inspect
~/.claude/settings.json— amodelSettings.<model>.effortLevelentry now exists and outranks the top-level key for every later session on that model. - Separately,
export ANTHROPIC_EFFORT=medium— no effect, no warning. export CLAUDE_CODE_EFFORT_LEVEL=high— applies, but/effortis now inert for the session.
Related issues
- #90419 — in-session effort changes not persisting when
CLAUDE_CODE_EFFORT_LEVELis set (symptom of point 3) - #63413 — session-only flag for typed
/model(same write-back-as-side-effect problem, model side) - #95347 —
effortLevelhas no session-scoped write channel - #82114 — per-model default effort levels (closed as not planned;
modelSettingsnow provides this, which is what makes point 1 reachable)
Environment
- Claude Code 2.1.241
Docs referenced
- https://code.claude.com/docs/en/env-vars (Precedence;
CLAUDE_CODE_EFFORT_LEVELrow) - https://code.claude.com/docs/en/settings (
effortLevel/modelSettingsresolution)