[BUG] `ANTHROPIC_DEFAULT_*_MODEL` in `settings.json` silently stripped under Desktop's `PROVIDER_MANAGED_BY_HOST`
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?
Summary
When Claude Code runs inside Claude Desktop (CLAUDE_CODE_ENTRYPOINT=claude-desktop), any ANTHROPIC_DEFAULT_*_MODEL override set via ~/.claude/settings.json's env block is filtered out before reaching process.env. The built-in Explore subagent is pinned to model: "haiku", so it ends up running as the host-default Haiku 4.5 with no way to redirect it. There is no warning or log about the filter.
Environment
- Claude Code: 2.1.111 (bundled in Claude Desktop)
- Entry point:
claude-desktop - OS: macOS 15.1 (Darwin 24.1.0)
Reproduction
- In
~/.claude/settings.json, set:
``json``
{
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-sonnet-4-6",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-4-6"
}
}
- Launch Claude Code via the Desktop app.
- Spawn an
Exploresubagent (e.g. via theAgenttool,subagent_type: "Explore"). - In the UI, the subagent is labeled "Haiku 4.5". In a Bash tool run, confirm:
````
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 (propagated)
ANTHROPIC_DEFAULT_HAIKU_MODEL=<unset> (stripped)
ANTHROPIC_DEFAULT_SONNET_MODEL=<unset> (stripped)
CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST=1 (set by host)
Expected
Either:
- The
ANTHROPIC_DEFAULT_*_MODELoverrides insettings.jsonshould take effect (thenGH()/vR()/bh()resolvers already read them correctly), or - Claude Code should surface a clear warning/log when it drops a user-supplied env var because it's provider-managed, so users know why their setting silently doesn't work.
Actual
The override is silently dropped. Explore continues to run on the host-default Haiku.
Root cause
Two functions in the bundled JS are responsible (names are minified):
// Denylist of "provider-managed" env keys
o01 = new Set([
"CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST", "CLAUDE_CODE_USE_BEDROCK", ...,
"ANTHROPIC_MODEL",
"ANTHROPIC_DEFAULT_HAIKU_MODEL", "ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME", ...,
"ANTHROPIC_DEFAULT_SONNET_MODEL", ...,
"ANTHROPIC_DEFAULT_OPUS_MODEL", ...,
"ANTHROPIC_SMALL_FAST_MODEL", "CLAUDE_CODE_SUBAGENT_MODEL",
...
]);
function UC9(H) {
let _ = H.toUpperCase();
return o01.has(_) || a01.some((q) => _.startsWith(q));
}
function BC5(H) {
if (!H) return {};
if (!VH(process.env.CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST)) return H; // no-op when host not managing
let _ = {};
for (let [q, K] of Object.entries(H))
if (!UC9(q)) _[q] = K;
return _;
}
BC5 is applied to the user's settings.json env block before it's merged into process.env. When the Desktop host sets CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST=1, every key in o01 is dropped. CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS is not in o01, which is why that same env block's other key DOES propagate — making the failure mode especially confusing.
Meanwhile the built-in Explore agent definition is:
{
agentType: "Explore",
source: "built-in",
model: "haiku",
...
}
and the "haiku" → concrete-model resolver respects the env var when it's set:
function nGH() {
if (process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL)
return process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL;
return M$()[tU];
}
So the override path would work end-to-end — it's only the upstream env-filter that breaks it.
Impact
- Users have no way to redirect the built-in
Exploreagent (or any agent pinned to"haiku"/"sonnet"/"opus") away from the host defaults when running under Desktop. - Cost/latency surprise: users who assumed their override applied are getting a different model than they configured.
- Debugging is hard because the filter is silent and the
envblock partially works (keys not ino01still propagate).
Suggested fixes (pick one or more)
- Honor
ANTHROPIC_DEFAULT_*_MODELfromsettings.jsoneven underPROVIDER_MANAGED_BY_HOST. The host only needs to manage auth/endpoint/account-level model gating; the alias → concrete-model mapping is a UX preference. - If keeping the filter, emit a warning to the status line / debug log when
BC5drops a user-supplied key, e.g."Ignored settings.json env var ANTHROPIC_DEFAULT_HAIKU_MODEL: managed by host". - Document the denylist in the
settings.jsondocs so users don't waste time configuring vars that won't take effect. - Optionally, expose a
modelsblock insettings.json(e.g."models": { "haiku": "claude-sonnet-4-6" }) that takes a different code path and isn't env-filtered.
Workarounds today
- Launch
claudefrom a terminal instead of Desktop —CLAUDE_CODE_PROVIDER_MANAGED_BY_HOSTisn't set, soBC5becomes a pass-through. - Pass
modelexplicitly on everyAgent(...)call (doesn't help with built-inExplore's default).
Related issues
Not a duplicate of any of these, but they share adjacent ground:
- #41533 — Same code path: Desktop's
PROVIDER_MANAGED_BY_HOSTfilter stripsCLAUDE_CODE_USE_FOUNDRYfromsettings.json, breaking Azure Foundry routing. Different user-facing symptom (provider routing vs. alias resolution), same underlyingBC5/UC9/o01mechanism. - #49925 — Same code path in Desktop SSH mode: the host injects
PROVIDER_MANAGED_BY_HOST=1on the remote and strips its Vertex/Bedrock config. SSH-specific manifestation of the same filter behavior. - #48365 — Reports the opposite behavior on Windows:
ANTHROPIC_DEFAULT_HAIKU_MODELfromsettings.jsonis injected in Desktop OAuth mode (and used by WebFetch), whileANTHROPIC_BASE_URLis not. Either the env filter is platform-gated (macOS strips, Windows doesn't?), version-gated (Windows reporter was on 2.1.109; this report on 2.1.111), or one of the observations is flawed. Would appreciate an Anthropic engineer clarifying the intended behavior across platforms/versions. - #47488 — Similar end-user symptom (subagents silently forced to Haiku) but different mechanism: in Cowork on Windows, the Electron host unconditionally injects
CLAUDE_CODE_SUBAGENT_MODEL=claude-haiku-4-5-20251001, overriding theAgenttool'smodel:parameter. Not the env-filter path; a spawn-site injection. Still a silent model override without any surfaced warning. - #43869 — CLI-side: every documented subagent model override mechanism (
model:param, frontmatter,CLAUDE_CODE_SUBAGENT_MODELenv var,settings.json envblock) silently resolves to the parent's model. Different root cause, but part of the same "subagent model routing is broken somewhere in the stack" pattern.
What Should Happen?
Either:
- The
ANTHROPIC_DEFAULT_*_MODELoverrides insettings.jsonshould take effect (thenGH()/vR()/bh()resolvers already read them correctly), or - Claude Code should surface a clear warning/log when it drops a user-supplied env var because it's provider-managed, so users know why their setting silently doesn't work.
Error Messages/Logs
Steps to Reproduce
- In
~/.claude/settings.json, set:
``json``
{
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-sonnet-4-6",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-4-6"
}
}
- Launch Claude Code via the Desktop app.
- Spawn an
Exploresubagent (e.g. via theAgenttool,subagent_type: "Explore"). - In the UI, the subagent is labeled "Haiku 4.5". In a Bash tool run, confirm:
````
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 (propagated)
ANTHROPIC_DEFAULT_HAIKU_MODEL=<unset> (stripped)
ANTHROPIC_DEFAULT_SONNET_MODEL=<unset> (stripped)
CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST=1 (set by host)
Claude Model
None
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.112
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Other
Additional Information
_No response_
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗