Skip to content
gentic.news — AI News Intelligence Platform
Connecting to the Living Graph…

Listen to today's AI briefing

Daily podcast — 5 min, AI-narrated summary of top stories

Developer inspecting a terminal with code showing model pin configuration errors in a subagent setup, surrounded by…

Your Subagent Model Pins Are Silently Breaking — Here's the 4-Layer Fix

Subagent model pins in Claude Code frontmatter (rank 3 of 4) can silently drop out, sending agents to your expensive session model. Use a PreToolUse hook to block Task calls to frontier models unless pinned.

·22h ago·4 min read··11 views·AI-Generated·Report error
Share:
Source: thomas-witt.comvia hn_claude_codeCorroborated
Why is my subagent running on Fable instead of Sonnet despite the model pin?

Claude Code resolves subagent models in 4 layers: frontmatter pin is rank 3, and it silently fails across releases. Fix: add a PreToolUse hook that blocks Task calls to expensive models unless pinned, and verify your version's precedence.

TL;DR

Claude Code's subagent frontmatter model pin can silently drop out, running cheap agents on expensive frontier models. Verify with a hook.

Key Takeaways

  • Subagent model pins in Claude Code frontmatter (rank 3 of 4) can silently drop out, sending agents to your expensive session model.
  • Use a PreToolUse hook to block Task calls to frontier models unless pinned.

What Changed — The Silent Model Pin Failure

You pin a subagent to model: sonnet in its frontmatter. You dispatch it two hundred times a day. It works. But somewhere between releases, that pin stops being honored — and your cheap, mechanical agents quietly run on your most expensive session model (Fable or Opus 5). No error. No warning. Just a token bill that doesn't match your gut feeling.

Thomas Witt hit this exact issue. He runs Claude Code with a big session model plus a zoo of subagents — gateway agents, formatters, checkers. At some point, token consumption stopped matching what he'd actually done. Nothing broke. Everything worked. It just cost more.

Why It Works — The 4-Layer Resolution Order

Claude Code resolves which model a subagent runs on in four layers. The frontmatter pin — the one that's documented, obvious, and writable once — sits at rank 3 of 4. That would be fine if rank 3 always held. It doesn't. Across several releases, the frontmatter layer has silently dropped out, and pinned agents fell straight through to rank 4: the session model.

The problem is amplified because the agents you bother to pin are, by definition, the ones you dispatch most often and look at least. They're the mechanical ones — fetch logs, filter, format, check. The kind of job that needs "a model that is obedient, not brilliant." Running those on Fable or Opus 5 is "paying frontier prices for grep with good manners."

How To Apply It — Verify Your Pins Now

Here's the fix. Don't trust the frontmatter. Add a PreToolUse hook that blocks Task calls to expensive models unless the subagent has an explicit pin.

How I stopped my Claude Code subagents from secretly running on Fable instead of Sonnet

Example hook — in .claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Task",
        "hook": "node ~/.claude/hooks/check-subagent-model.mjs"
      }
    ]
  }
}

The hook script reads the subagent's frontmatter. If model is missing or set to a frontier model (Fable, Opus), it blocks the dispatch with a clear message:

// check-subagent-model.mjs
import { readFile } from 'fs/promises';
import { join } from 'path';

const agentDir = join(process.env.HOME, '.claude', 'agents');
const subagentName = process.env.CLAUDE_SUBAGENT_NAME; // set by Claude Code

if (!subagentName) {
  process.exit(0); // not a subagent call
}

const agentFile = join(agentDir, `${subagentName}.md`);
const content = await readFile(agentFile, 'utf8');

const modelMatch = content.match(/^model:\s*(.+)$/m);
const model = modelMatch ? modelMatch[1].trim() : null;

const expensive = ['fable', 'opus'];
if (!model || expensive.some(m => model.toLowerCase().includes(m))) {
  console.error(`BLOCKED: Subagent ${subagentName} has no model pin or is pinned to an expensive model. Add 'model: sonnet' to its frontmatter.`);
  process.exit(1); // blocks the Task call
}

process.exit(0);

Verify your version's precedence: Precedence behavior changes between Claude Code releases. Check the current docs or test with a debug subagent that echoes its model name. Add this to your subagent's prompt: "Print the model you are running on." If it says Fable when you pinned Sonnet, your pin is broken.

Audit your existing agents: Run this one-liner to list all agents and their pins:

for f in ~/.claude/agents/*.md; do echo "$f: $(grep '^model:' $f || echo 'NO PIN')"; done

Any agent with NO PIN or a frontier model is a candidate for the hook.

The Takeaway

Subagents are good — they run in their own context window, fetch a lot, filter, and return a little. But if you're paying frontier prices for that, you're wasting money. Pin them properly, verify the pin holds, and add a hook to catch silent failures. The crash is painful; the silent cost is worse.


Source: thomas-witt.com

Source: gentic.news · · author= · citation.json

AI-assisted reporting. Generated by gentic.news from multiple verified sources, fact-checked against the Living Graph of 4,300+ entities. Edited by Ala SMITH.

Following this story?

Get a weekly digest with AI predictions, trends, and analysis — free.

AI Analysis

**What should Claude Code users do differently?** First, stop trusting frontmatter pins as a guarantee. Add a PreToolUse hook that blocks Task calls to expensive models when the subagent lacks a proper pin. This turns a silent failure into a loud, actionable error. Second, audit your existing subagents — run the grep one-liner above to find any without a `model:` line. Third, verify your Claude Code version's precedence rules, since they change between releases. Test with a subagent that prints its model name. **Workflow changes**: For every subagent you create, add `model: sonnet` (or your preferred cheap model) in the frontmatter — even if you think it's obvious. Then add the hook to enforce it. This is a 10-minute setup that prevents recurring token waste. Also, consider reviewing your token usage weekly — if it doesn't match your actual work, suspect silent model fallback before anything else. The knowledge graph shows Claude Code's recent releases (2.1.221, 2.1.224) added security and parallelism features — but this model resolution bug persists across versions, so defense-in-depth is essential.
Enjoyed this article?
Share:

AI Toolslive

Five one-click lenses on this article. Cached for 24h.

Pick a tool above to generate an instant lens on this article.

Related Articles

From the lab

The framework underneath this story

Every article on this site sits on top of one engine and one framework — both built by the lab.

More in Products & Launches

View all