Skill frontmatter `model:` override ignored in interactive mode but honored in print mode (v2.1.227)

Status Open
Maintainer reply ✓ Yes — bcherny
Activity 3 comments · opened Aug 11, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Description

The model: field in SKILL.md frontmatter is documented to override the session model for the turn that invokes the skill. In interactive TUI sessions the override is parsed and recorded but not applied: the turn is served by the session model. In headless print mode (claude -p) the same skill is correctly served by the pinned model.

Related: #45191 reported this in April 2026 and was closed by the stale bot without triage. Filing fresh per the bot's instruction, with a repro that isolates interactive vs print mode.

Environment

Claude Code v2.1.227, macOS (Darwin 25.5.0), zsh.

Steps to reproduce

  1. Create ~/.claude/skills/model-probe/SKILL.md:

```yaml
---
name: model-probe
description: Diagnostic probe
disable-model-invocation: true
model: sonnet
---

Reply with exactly one word: OK
```

  1. Interactive: run claude --model opus, type /model-probe
  2. Headless: run claude -p "/model-probe" --model opus
  3. Compare message.model on the assistant turns in the two session transcripts (~/.claude/projects/<project>/<session>.jsonl)

Results

Interactive: the transcript records the attachment {"type":"command_permissions","allowedTools":[],"model":"claude-sonnet-5"}, then all assistant turns show "model":"claude-opus-5". Override recorded, not applied.

Headless: same attachment, assistant turn shows "model":"claude-sonnet-5". Override applied.

Also reproduced with haiku pins, resumed sessions with prior history, and --dangerously-skip-permissions. Print mode honors the pin in every combination tested; interactive never does.

Expected

Interactive invocation serves the turn on the pinned model per the docs ("The override applies for the rest of the current turn and is not saved to settings"), or the docs state the field is print-mode only.

View original on GitHub ↗

3 Comments

wenqin-xie · 18 days ago

Reproduced on v2.1.229 (macOS, Darwin 25.4.0), with two additional datapoints:

  1. Custom slash commands (~/.claude/commands/*.md) are affected too, not just skills. A command with model: sonnet + effort: medium in frontmatter, invoked interactively by typing /<command>: the transcript records {"type":"command_permissions","allowedTools":[...],"model":"claude-sonnet-5"} immediately after the command expansion, then the assistant turn that executes the command's task shows "model":"claude-fable-5" (the session model, which had been selected via /model mid-session). Same signature as the OP: recorded, not applied.
  1. In print mode the frontmatter pin even beats an explicit --model flag. claude -p "/<command>" and claude -p --model claude-fable-5 "/<command>" both serve the turn on claude-sonnet-5 (verified via message.model in the session JSONL). So the divergence is cleanly interactive-vs-print, not a precedence question — in print mode the override wins against everything we tried; in interactive mode it never applies.

Happy to provide the sanitized JSONL excerpts if useful.

bcherny collaborator · 15 days ago

Reproduced on v2.1.233 (macOS).

Steps:

  1. In a fresh project, create .claude/skills/model-probe/SKILL.md:

```yaml
---
name: model-probe
description: Diagnostic probe
disable-model-invocation: true
model: sonnet
---

Reply with exactly one word: OK
```

  1. Print mode: claude -p "/model-probe" --model opus --session-id <A>
  2. Interactive: claude --model opus --session-id <B>, type /model-probe, Enter
  3. Compare "model" on the assistant entries in ~/.claude/projects/<project>/<A|B>.jsonl

Observed:

== print-mode session
"command_permissions","allowedTools":[],"model":"claude-sonnet-5"
"model":"claude-sonnet-5"        <- assistant turn
== interactive session
"command_permissions","allowedTools":[],"model":"claude-sonnet-5"
"model":"claude-opus-5"          <- assistant turn

Print mode's JSON result also reports modelUsage only for claude-sonnet-5, while the interactive turn was billed to Opus.

Expected: the interactive /model-probe turn should be served by the skill's pinned model (sonnet), the same as print mode.

Assessment: This looks like a genuine bug, and a regression. The docs say the skill's model field applies for the rest of the current turn, and it did in interactive sessions until roughly v2.1.203–2.1.205 (July 2026), when interactive turns moved onto the same turn engine that print mode uses. In interactive mode the session's model gets re-applied on top of the per-turn skill pin, so the pin is recorded but never wins; print mode merges the skill pin differently and is unaffected. Custom slash commands with model: in frontmatter go through the same path, which matches the second report here. Still present in the current source.

🤖 Generated with Claude Code

yen81xxxx · 12 days ago

Reproduced on Windows 11 (10.0.26200), extending platform coverage beyond macOS — on both v2.1.229 and v2.1.234 (the latter in a fresh interactive session started after the frontmatter edit, so no stale cache in play).

  • User-level skill with model: sonnet + effort: medium in frontmatter (no context: fork)
  • Session model: claude-fable-5, permission mode bypassPermissions
  • Typing /<skill> interactively: the transcript records {"type":"command_permissions","allowedTools":[],"model":"claude-sonnet-5"} at invocation, then every assistant turn in that invocation records "model":"claude-fable-5" — same recorded-but-not-applied signature as the OP.

So: not macOS-specific, still present on v2.1.234, and independent of the session model family.