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.json or --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 the Agent/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:
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.
Description
When
availableModelsandmodelOverridesare both configured insettings.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: sonnetin a.claude/agents/*.mdfile) or as--model sonneton the CLI. Instead of resolving throughmodelOverrideslike 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_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
~/.claude/settings.jsonor--settings).claude --model opus, then invoke the subagent (e.g. via theAgent/Task tool).--debug-file).Observed behavior
The subagent runs on Opus instead of Sonnet, silently ignoring the frontmatter
model: sonnetdirective. This reproduces consistently across severalavailableModels/modelOverridesvariations, 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
/modelcommand surfaces an explicit error for the same alias:Expected behavior
Using the full canonical name works correctly in all cases:
The bare alias should resolve through
modelOverridesthe same way the full name does — i.e., alias resolution should happen before (or account for) themodelOverridesmapping 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 literalstartsWithmatch against theavailableModelsallowlist 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.