Skip to content

Bare model aliases (sonnet/opus/haiku/fable) fail to resolve through modelOverrides in subagent frontmatter and --model #81995

Description

@jstrunk

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

  1. Apply the settings above (via ~/.claude/settings.json or --settings).
  2. 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.
  1. Start a session on a different model family, e.g. claude --model opus, then invoke the subagent (e.g. via the Agent/Task tool).
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions