Bare model aliases (sonnet/opus/haiku/fable) fail to resolve through modelOverrides in subagent frontmatter and --model
Description
When availableModels and modelOverrides are both configured in settings.json (common for Bedrock/enterprise setups that map canonical model names to provider-specific inference profile IDs), bare model aliases (sonnet, opus, haiku, fable) fail validation when used in subagent frontmatter (model: sonnet in a .claude/agents/*.md file) or as --model sonnet on the CLI. Instead of resolving through modelOverrides like the full canonical name does, the alias silently falls back to the parent/default model with a warning, or is rejected outright depending on the code path.
Environment
- Claude Code version: 2.1.220
- Provider: Amazon Bedrock (
CLAUDE_CODE_USE_BEDROCK=1)
Minimal repro settings.json
{
"availableModels": [
"claude-opus-5",
"claude-sonnet-5",
"claude-fable-5",
"claude-haiku-4-5"
],
"enforceAvailableModels": false,
"modelOverrides": {
"claude-opus-5": "global.anthropic.claude-opus-5[1m]",
"claude-sonnet-5": "global.anthropic.claude-sonnet-5[1m]",
"claude-fable-5": "global.anthropic.claude-fable-5[1m]",
"claude-haiku-4-5": "global.anthropic.claude-haiku-4-5-20251001-v1:0"
}
}
Repro steps
- Apply the settings above (via
~/.claude/settings.jsonor--settings). - Create a subagent with bare-alias frontmatter:
---
name: test-sonnet-agent
description: test agent pinned to sonnet
model: sonnet
---
You are a test agent. When invoked, just say hi.
- Start a session on a different model family, e.g.
claude --model opus, then invoke the subagent (e.g. via theAgent/Task tool). - Check debug logs (
--debug-file).
Observed behavior
[WARN] Subagent model "sonnet" is not in the availableModels allowlist; inheriting the parent model instead
...
dispatching to bedrock model=global.anthropic.claude-opus-5[1m]
The subagent runs on Opus instead of Sonnet, silently ignoring the frontmatter model: sonnet directive. This reproduces consistently across several availableModels/modelOverrides variations, including ones that list the raw Bedrock inference-profile strings directly.
Separately, claude --model sonnet -p "..." (headless CLI flag, same settings) also silently falls back to Opus 5 with no warning at all — worse than the subagent case, which at least logs a WARN.
By contrast, the interactive /model command surfaces an explicit error for the same alias:
Model 'sonnet' is not available. Your organization restricts model selection.
Expected behavior
Using the full canonical name works correctly in all cases:
model: claude-sonnet-5
dispatching to bedrock model=claude-sonnet-5
The bare alias should resolve through modelOverrides the same way the full name does — i.e., alias resolution should happen before (or account for) the modelOverrides mapping and the resulting provider-native model ID (e.g. global.anthropic.claude-sonnet-5[1m]) should be checked for membership via the reverse override mapping, not a literal startsWith match against the availableModels allowlist entries.
Impact
Any org using Bedrock/Vertex/Foundry with modelOverrides (needed to map canonical Claude names to provider-specific inference profile ARNs/IDs) cannot reliably use short model aliases in subagent frontmatter or --model — they must always spell out full canonical names. This is easy to trip over silently, since two of the three failure modes produce no visible error (silent fallback to a different, possibly more expensive model) and only one produces an explicit rejection.
3 Comments
Apologies if I have misunderstood any of the implementation details. I do not usually comment on GitHub issues.
I came across this issue after noticing unexpected behavior on Amazon Bedrock when using
availableModels,modelOverrides, and/model. I searched through a number of existing issues to see whether others had encountered similar behavior, which eventually led me here.After reading the current Model configuration documentation, most of the per-surface behavior in this report appears to match what the documentation describes. One unresolved exception is
--model: the documentation says that substitution occurs with a warning naming both the requested and substituted models, while this report says that the substitution is silent.My broader interest is cross-provider consistency. I use Claude Code through a personal Claude subscription for research, but Amazon Bedrock in my work environment. Being able to reuse the same agent definitions and model-selection settings with equivalent behavior would make it much easier to transfer workflows between those environments.
I understand that this may be a feature request rather than a bug under the current documentation. Still, I hope the team will consider bringing Bedrock and other provider-specific deployments closer to the alias-resolution behavior available with Anthropic-hosted usage. The related issues below may be different manifestations of the same boundary between Claude's canonical model identity and provider-specific deployment IDs.
Separately, the missing
--modelwarning appears to be a narrower, independently actionable issue. One detail would help confirm it: was stderr captured in the non-interactive reproduction?If
stderr.txtis empty, the missing warning appears to be a clear documentation-versus-implementation mismatch. If the warning is present there, the broader portability question remains.---
<details>
<summary>Detailed comparison with the current documentation, cross-provider implications, and possibly related issues</summary>
Documented per-surface behavior
Restrict model selection says that on Amazon Bedrock and other providers using provider-specific deployment IDs, a blocked family alias follows the rejection or replacement path rather than resolving to the newest permitted version of its family. The alias-to-newest-permitted-version behavior introduced in v2.1.205 is documented for the Anthropic API and Claude Platform on AWS, not Amazon Bedrock.
Blocked aliases then follow per-surface rules:
| Where specified | Documented behavior | This report |
| ---------------------------------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
|
/model| Rejected with an error | Matches ||
--model,ANTHROPIC_MODEL, or themodelsetting | Replaced at startup with a warning naming both the requested and substituted models | Replacement matches; whether the warning was emitted to stderr is not yet clear || Subagent, skill, or command frontmatter | Falls back to the inherited or default model | The reported subagent behavior matches, with a warning in the debug log |
The surface-specific outcomes themselves therefore appear to be documented. They may not represent three separate defects.
Yet the distinction has a concrete consequence: a configuration that is portable in form is not necessarily portable in behavior.
Cross-provider consistency
From a user's perspective, the desired invariant seems simple: when an organization permits a Sonnet model,
model: sonnetshould select an allowed Sonnet model in both Anthropic-hosted and Bedrock environments. The organization should still control the permitted version, andmodelOverridesshould still control the provider-native ID ultimately sent to Bedrock.Today, the same family alias can resolve normally in one environment but be rejected or replaced in another. In subagent frontmatter, that replacement may silently change the model family by inheriting the parent model. This makes agent definitions developed in one environment less reliable when transferred to another, even when both environments are intended to expose the same Claude model families.
The warning behavior matters, but a warning alone would not restore that portability.
The
--modelwarning may be independently actionableThe documentation says that an excluded startup selection is replaced with a warning naming both the requested and substituted models. This report says that
claude --model sonnet -p "..."falls back to Opus 5 without any visible warning.That is a consequential failure mode: the session can run on a different, possibly more expensive model without making the substitution visible to the caller.
The documentation separately notes that model-remapping warnings are written to stderr in non-interactive mode when the default text output format is used. Those warnings are suppressed with
--output-format jsonorstream-json.I could not determine from the documentation alone whether an allowlist-substitution warning uses the same stderr path. If the warning appears in
stderr.txt, the behavior may be consistent with the documentation even though it is easy to miss. If stderr is also empty, the missing warning stands as a narrow implementation-versus-documentation mismatch regardless of how the broader alias-resolution question is resolved.availableModelsandmodelOverridesThe reproduction lists full model IDs such as
claude-sonnet-5while selecting the family aliassonnet.The
modelOverridessection says that allowlist matching is performed against the Anthropic model ID rather than the provider-specific override value. It also says that overrides apply when an Anthropic model ID is supplied directly through model-selection settings.That makes the boundary between a full model ID and a family alias worth isolating.
Testing family entries may help:
This gives up strict version pinning, so it is not necessarily a suitable production configuration. As a diagnostic comparison, however, it may show whether the alias is being rejected during allowlist matching before
modelOverridescan apply.If this is tested, the debug log should also be checked to confirm which provider-native model ID was actually dispatched. Successful startup alone would show only that the alias passed the allowlist, not that it reached the intended Bedrock inference profile.
Possible framing
This appears to contain two related concerns:
--model <alias>is substituted without the documented warning, if stderr is also empty when using the text output format.The second concern may be independently actionable, but resolving it would not address the broader portability problem.
Possibly related:
/modeldrops the Sonnet 1M entry whenavailableModelsandmodelOverridesare combined; closed as not planned and currently labeled staleANTHROPIC_DEFAULT_*_MODELcan be selected through/model <alias>but do not appear in the/modelpicker; currently openI am reading the documentation rather than the implementation, so I may be missing constraints imposed by provider-specific deployment IDs. Even so, the user-facing portability gap remains. If the stderr capture is also empty, the missing
--modelwarning stands on its own.</details>
---
English is not my first language, and while I can read it reasonably well, I am not very experienced in writing technical comments in English. I researched this as carefully as I could and used AI to help organize and express my findings, so I apologize if any part comes across as AI-generated noise, is unnecessarily verbose, or misses the point.
Thank you to the Claude team and the community for all the work that makes this project possible.
Thanks for the precise writeup — reproduced on the current release (2.1.233, Linux) using your exact
settings.json:claude --model sonnet -p ...silently runs on the default model (Opus, via its override) with no warning at all — confirmed via debug logs showing the request dispatched to the Opus inference profile.claude --model claude-sonnet-5 -p ...correctly targets Sonnet, as you found./model sonnetshows the explicit "Model 'sonnet' is not available. Your organization restricts model selection." error.So the core problem stands: with an
availableModelsallowlist of canonical names plusmodelOverrides, bare family aliases fail the allowlist check even though the family they resolve to is clearly permitted — and the headless--modelpath does this silently, which is the most dangerous of the three behaviors. Marking as a confirmed bug.One partial improvement to note: since 2.1.222 (after the 2.1.220 you tested), subagent/teammate frontmatter family aliases that fail the allowlist now step down to the newest org-allowed model in that family instead of inheriting the parent model, which should mitigate the
model: sonnetfrontmatter case specifically. The--modelflag and alias-resolution inconsistency remain, as does the silent (no-warning) fallback. Until it's fixed, spelling out full canonical names is the reliable workaround, as you noted.🤖 Generated with Claude Code
For your information: the label reproduced on this issue does not prevent it from becoming stale and eventually auto-closed. See https://github.com/anthropics/claude-code/issues/87647 for details, and consider upvoting that for visibility.