[BUG] Claude Code does not respect agent model definition, uses wrong model.
Status Closed — not planned
Reported on v2.1.7
Maintainer reply None cached
Workaround ✓ Mentioned in thread ↓
Activity 14 comments · opened Jan 15, 2026 · closed Jun 11, 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?
I've setup agents like this:
---
name: code-implementer
description: ---- redacted -----
model: opus
color: red
---
but when claude calls this model it uses sonnet:
code-implementer(job) resuming af473b5 Sonnet 4.5
This bug greatly reduces code quality, reasoning quality and other tasks quality. (planning, reviewing, etc.)
What Should Happen?
Claude should use opus for subagent because it's defined as opus.
Error Messages/Logs
no error. it just uses other models, without any reason.
Steps to Reproduce
- Create an agent as opus.
- Tell claude to delegate work to said agent.
- Agent uses other model.
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
2.1.?
Claude Code Version
2.1.7
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_
Showing cached comments. Read the full discussion on GitHub ↗
13 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
anyone?
Same issue here with team agents (TeamCreate + Task tool). Running Claude Code 2.1.37 on Linux WSL2 with parent model Opus 4.6. When spawning a teammate with
model: "sonnet", the agent silently runs under Opus 4.6 instead. No error, no 404 — just silently ignored. See #24429 for full reproduction steps.I had opposite problem today - Mine agent is defined with
sonnetmodel, but it was executed withopusmultiple times.btw. I had there quite long description text. I made it shorter (2 liner) and I didn't see wrong model used there from that time.
I did some digging into the
Task tool, and the main agent can and will override subagent models in tasks unpredictably.Observed Behaviors:
modelparametermodel:not enforcedmodelparameterControlled test results confirming team-specific model override bug
Ran three controlled rounds on Claude Code v2.1.37 (macOS, Opus 4.6 parent) to isolate the behavior. Each agent was asked to self-report its model from its system prompt.
Round 1: Team dispatch, NO model parameter
| Agent | Expected | Actual | Match? |
|-------|----------|--------|--------|
| Geth (frontmatter: haiku) | haiku | Opus 4.6 | No |
| EDI (frontmatter: sonnet) | sonnet | Opus 4.6 | No |
| Liara (frontmatter: opus) | opus | Opus 4.6 | Yes (coincidental) |
Round 2: Team dispatch, EXPLICIT model parameter
| Agent | Requested | Actual | Match? |
|-------|-----------|--------|--------|
| Geth | haiku | Opus 4.6 | No |
| EDI | sonnet | Opus 4.6 | No |
| Liara | opus | Opus 4.6 | Yes (coincidental) |
Round 3: Standalone subagent dispatch (no team), EXPLICIT model parameter
| Agent | Requested | Actual | Match? |
|-------|-----------|--------|--------|
| Geth | haiku | Haiku 4.5 (claude-haiku-4-5-20251001) | Yes |
| EDI | sonnet | Sonnet 4.5 (claude-sonnet-4-5-20250929) | Yes |
| Liara | opus | Opus 4.6 (claude-opus-4-6) | Yes |
Conclusion
The
modelparameter on the Task tool works correctly for standalone subagent dispatches but is silently ignored for team-spawned teammates (viateam_name+nameparameters). All teammates inherit the parent's model regardless of explicitmodelparam or agent frontmattermodel:declaration.This has direct cost implications — teams designed to use tiered models (haiku for simple tasks, sonnet for standard work) silently run everything at the leader's model cost.
Root cause analysis in #27038 traces it to the
handleSpawnInProcessfunction where the resolved model value is computed but never passed to the runner.Related: #27038, #24429, #24668
met issue like this.
version:2.1.72 (Claude Code)
sence: Ghostty
model: opusplan
status: in plan mode
issue: Explore subagent use opus but not haiku.
try-fix: Wrote some prompt that tell Claude code when it want to fire Explore subagent then use Haiku, not by inherit.
result: not work. I saw the gray text declare the Explore Agent used Haiku4.5, but actual Opus by capture http.
Hope u guys fix it, save my money!
@cheeselemon — this is a model alias resolution issue. I built claude-alias-patch that fixes the alias resolver so agent model definitions actually work. It also lets you register custom aliases beyond sonnet/opus/haiku via
ANTHROPIC_DEFAULT_*_MODELenv vars.Single install script, auto-patches your Claude instance. Tested and working — agents respect their frontmatter model field after patching.
Related but distinct bug: tmux backend strips [1m] context window from teammates
The tmux split-pane backend strips the \
[1m]\suffix when spawning teammates, giving them 200K context instead of 1M. This is distinct from this issue's model selection bug — here the model is correct but the context window variant is wrong.Confirmed workaround (credit @Reasonably, confirmed on v2.1.92):
"teammateDefaultModel": null\to \~/.claude.json\/model opus[1m]\in the lead session (NOT "Default (recommended)")model\when spawning teammatesBug is tmux-specific — in-process mode and non-tmux terminals give teammates 1M without any workaround.
Canonical issue: #34421. Full details and before/after screenshots there.
Confirming this issue on CLI v2.1.114. Subagent
modelfrontmatter and the Agent toolmodelparameter are both ignored for Opus specifically, whilesonnetandhaikuvalues still route correctly.Environment
claude-opus-4-7(direct Anthropic API, Max plan auth).claude/agents/*.mdReproduction
.claude/agents/{name}.mdfrontmatter, set the model using the full ID:Agent(subagent_type="infra-manager", model="opus", ...)
The exact model ID is ...).claude-sonnet-4-6regardless of frontmatter or Agent-tool argument.Variations tested (all produce the same Sonnet result for Opus)
| Config | Result |
|---|---|
| frontmatter
model: claude-opus-4-7| Sonnet 4.6 (ignored) || frontmatter
model: opus(alias) | Sonnet 4.6 (ignored) || Agent tool
model: "opus"| Sonnet 4.6 (ignored) || Agent tool
model: "sonnet"| Sonnet 4.6 (as expected) || Agent tool
model: "haiku"| Haiku (as expected) |So the bug is Opus-specific:
sonnetandhaikurouting paths are honored; onlyopussilently falls back to the default Sonnet.Evidence (subagent self-report excerpt)
You are powered by the model named Opus 4.
The exact model ID is claude-sonnet-4-6.
The "Opus 4" display name is injected from the frontmatter, but the actual
exact model IDline — which reflects the real runtime binding — showsclaude-sonnet-4-6. This mismatch is the clearest signal that the frontmatter is cosmetic and the routing layer is not applying the Opus binding.Workaround that works
Adding the following to
settings.jsonrestores Opus 4.7 for all subagents:After restart, every subagent self-reports
claude-opus-4-7and behaves accordingly.Caveats for others hitting this:
claude-opus-4-7-20260416return404 model_not_foundfrom the API; the undatedclaude-opus-4-7is the only value that works here.Questions for maintainers
modelapplication path implemented separately from theCLAUDE_CODE_SUBAGENT_MODELenv path? The asymmetry (env works, frontmatter silently ignored, Sonnet/Haiku aliases work, Opus alias does not) suggests the Opus alias is missing from the per-agent resolver table while present in the env resolver.Happy to provide full
claude --debuglogs or a minimal repro repo if useful.Confirming this issue on CLI v2.1.114. Subagent
modelfrontmatter and the Agent toolmodelparameter are both ignored for Opus specifically, whilesonnetandhaikuvalues still route correctly.Environment
claude-opus-4-7(direct Anthropic API, Max plan auth).claude/agents/*.mdReproduction
.claude/agents/{name}.mdfrontmatter, set the model using the full ID:Agent(subagent_type="infra-manager", model="opus", ...)
The exact model ID is ...).claude-sonnet-4-6regardless of frontmatter or Agent-tool argument.Variations tested (all produce the same Sonnet result for Opus)
| Config | Result |
|---|---|
| frontmatter
model: claude-opus-4-7| Sonnet 4.6 (ignored) || frontmatter
model: opus(alias) | Sonnet 4.6 (ignored) || Agent tool
model: "opus"| Sonnet 4.6 (ignored) || Agent tool
model: "sonnet"| Sonnet 4.6 (as expected) || Agent tool
model: "haiku"| Haiku (as expected) |So the bug is Opus-specific:
sonnetandhaikurouting paths are honored; onlyopussilently falls back to the default Sonnet.Evidence (subagent self-report excerpt)
You are powered by the model named Opus 4.
The exact model ID is claude-sonnet-4-6.
The "Opus 4" display name is injected from the frontmatter, but the actual
exact model IDline — which reflects the real runtime binding — showsclaude-sonnet-4-6. This mismatch is the clearest signal that the frontmatter is cosmetic and the routing layer is not applying the Opus binding.Workaround that works
Adding the following to
settings.jsonrestores Opus 4.7 for all subagents:After restart, every subagent self-reports
claude-opus-4-7and behaves accordingly.Caveats for others hitting this:
claude-opus-4-7-20260416return404 model_not_foundfrom the API; the undatedclaude-opus-4-7is the only value that works here.Questions for maintainers
modelapplication path implemented separately from theCLAUDE_CODE_SUBAGENT_MODELenv path? The asymmetry (env works, frontmatter silently ignored, Sonnet/Haiku aliases work, Opus alias does not) suggests the Opus alias is missing from the per-agent resolver table while present in the env resolver.Happy to provide full
claude --debuglogs or a minimal repro repo if useful.Reporting the inverse direction on v2.1.139 Windows. Your issue: configured-Opus runs Sonnet. Mine: model picker shows Sonnet on first step, continues to reveal Opus on second step — every single agent-mode window, despite Sonnet being set in the agent configuration files. Billing ran Opus for 11 hours overnight. Filed as #58450 with screenshots. The model tier tracking between display and billing is unreliable in both directions.
Closing for now — inactive for too long. Please open a new issue if this is still relevant.