{
 "id": 2254,
 "status": "publish",
 "lang": "en",
 "slug": "claude-code-headless-model-detection",
 "url": "https://soymarketingultra.com/en/claude-code-headless-model-detection/",
 "title": "Claude Code Ghost Haiku: Fix Your Model Detection",
 "excerpt": "Claude Code mixes internal Haiku calls with your real model work in headless mode. Here's the robust fix to detect which model actually ran.",
 "date_gmt": "2026-06-25T07:34:26Z",
 "modified_gmt": "2026-07-16T19:40:06Z",
 "categories": [
  {
   "slug": "seo-en",
   "name": "SEO",
   "url": "https://soymarketingultra.com/en/category/seo-en/"
  }
 ],
 "tags": [
  {
   "slug": "ai-automation",
   "name": "AI automation"
  },
  {
   "slug": "claude-code-en",
   "name": "Claude Code"
  },
  {
   "slug": "llm-pipeline",
   "name": "llm pipeline"
  },
  {
   "slug": "model-detection",
   "name": "model detection"
  },
  {
   "slug": "production-ai",
   "name": "production ai"
  }
 ],
 "featured_image": {
  "url": "https://soymarketingultra.com/wp-content/uploads/cabecera-2254.png",
  "alt": "Article header: Claude Code Ghost Haiku: Fix Your Model Detection",
  "width": 1200,
  "height": 675
 },
 "translation": {
  "lang": "es",
  "url": "https://soymarketingultra.com/claude-code-headless-haiku-guard/",
  "id": 2252
 },
 "seo": {
  "title": "Claude Code Ghost Haiku: Fix Your Model Detection",
  "description": "Claude Code mixes internal Haiku calls with your real model work in headless mode. Here's the robust fix to detect which model actually ran.",
  "focus_keyword": "claude code headless model detection"
 },
 "html": "<p>You set up a quality guard for your AI pipeline. The order is clear: if a cheap model generates the content, stop it before it goes live. And the guard does its job. Several times over two weeks, it throws out perfectly good work from your expensive model. The reason? Claude Code uses Haiku internally to name the session, and your guard can’t tell that internal call apart from the real work.</p>\n\n<p>The killer calling the cops. Welcome to running LLMs in production.</p>\n\n<div class=\"mu-tldr\">\n  <div class=\"mu-tldr__header\">\n    <img src=\"https://soymarketingultra.com/wp-content/themes/astra-child/assets/brand/despiram-sorprendido.png\" alt=\"Marketing Ultra Mascot\" class=\"mu-tldr__mascot\" />\n    <p class=\"mu-tldr__title\">TL;DR: The No-Nonsense Summary</p>\n  </div>\n  <div class=\"mu-tldr__body\">\n    <ul>\n      <li><strong>Ghost Haiku</strong>: Claude Code runs internal Haiku calls for auxiliary tasks (session naming, routing) that show up in <code>.modelUsage</code> alongside your real work. Your guard mistakes them for the model that actually did the job.</li>\n      <li><strong>Three heuristics, three failures</strong>: first model alphabetically, highest token count, and exact ID match all fail for the same reason: internal model calls mixed in with real work.</li>\n      <li><strong>The <code>--model</code> flag doesn’t work</strong>: in <code>claude -p</code> headless mode, only the <code>ANTHROPIC_MODEL</code> env variable is respected. Without setting it explicitly, the CLI may use a stale default or silently downgrade to Haiku.</li>\n      <li><strong>Robust fix</strong>: exclude Haiku from <code>.modelUsage</code>, then pick the highest-output-token model from what’s left. Only if everything is Haiku is it a real downgrade.</li>\n    </ul>\n    <div class=\"mu-tldr__verdict\"><svg class=\"mu-tldr__gavel\" aria-hidden=\"true\" viewBox=\"0 0 26 18\" width=\"40\" height=\"28\" shape-rendering=\"crispEdges\" style=\"image-rendering:pixelated\"><rect x=\"6\" y=\"0\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"7\" y=\"0\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"8\" y=\"0\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"5\" y=\"1\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"6\" y=\"1\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"7\" y=\"1\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"8\" y=\"1\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"9\" y=\"1\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"10\" y=\"1\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"5\" y=\"2\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"6\" y=\"2\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"7\" y=\"2\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"8\" y=\"2\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"9\" y=\"2\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"10\" y=\"2\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"11\" y=\"2\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"12\" y=\"2\" width=\"1\" height=\"1\" fill=\"#696969\"/><rect x=\"5\" y=\"3\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"6\" y=\"3\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"7\" y=\"3\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"8\" y=\"3\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"9\" y=\"3\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"10\" y=\"3\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"11\" y=\"3\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"12\" y=\"3\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"13\" y=\"3\" width=\"1\" height=\"1\" fill=\"#696969\"/><rect x=\"5\" y=\"4\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"6\" y=\"4\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"7\" y=\"4\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"8\" y=\"4\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"9\" y=\"4\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"10\" y=\"4\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"11\" y=\"4\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"12\" y=\"4\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"13\" y=\"4\" width=\"1\" height=\"1\" fill=\"#8a7060\"/><rect x=\"4\" y=\"5\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"5\" y=\"5\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"6\" y=\"5\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"7\" y=\"5\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"8\" y=\"5\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"9\" y=\"5\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"10\" y=\"5\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"11\" y=\"5\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"12\" y=\"5\" width=\"1\" height=\"1\" fill=\"#8a7060\"/><rect x=\"4\" y=\"6\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"5\" y=\"6\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"6\" y=\"6\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"7\" y=\"6\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"8\" y=\"6\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"9\" y=\"6\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"10\" y=\"6\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"11\" y=\"6\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"2\" y=\"7\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"3\" y=\"7\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"4\" y=\"7\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"5\" y=\"7\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"6\" y=\"7\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"7\" y=\"7\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"8\" y=\"7\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"9\" y=\"7\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"10\" y=\"7\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"11\" y=\"7\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"2\" y=\"8\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"3\" y=\"8\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"4\" y=\"8\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"5\" y=\"8\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"6\" y=\"8\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"7\" y=\"8\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"8\" y=\"8\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"9\" y=\"8\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"10\" y=\"8\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"11\" y=\"8\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"12\" y=\"8\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"13\" y=\"8\" width=\"1\" height=\"1\" fill=\"#8a7060\"/><rect x=\"17\" y=\"8\" width=\"1\" height=\"1\" fill=\"#696969\"/><rect x=\"18\" y=\"8\" width=\"1\" height=\"1\" fill=\"#b87575\"/><rect x=\"19\" y=\"8\" width=\"1\" height=\"1\" fill=\"#8a7060\"/><rect x=\"20\" y=\"8\" width=\"1\" height=\"1\" fill=\"#8a7060\"/><rect x=\"21\" y=\"8\" width=\"1\" height=\"1\" fill=\"#8a7060\"/><rect x=\"22\" y=\"8\" width=\"1\" height=\"1\" fill=\"#8a7060\"/><rect x=\"23\" y=\"8\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"1\" y=\"9\" width=\"1\" height=\"1\" fill=\"#8a7060\"/><rect x=\"2\" y=\"9\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"3\" y=\"9\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"4\" y=\"9\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"5\" y=\"9\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"6\" y=\"9\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"7\" y=\"9\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"8\" y=\"9\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"9\" y=\"9\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"10\" y=\"9\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"11\" y=\"9\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"12\" y=\"9\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"13\" y=\"9\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"14\" y=\"9\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"15\" y=\"9\" width=\"1\" height=\"1\" fill=\"#8a7060\"/><rect x=\"16\" y=\"9\" width=\"1\" height=\"1\" fill=\"#696969\"/><rect x=\"17\" y=\"9\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"18\" y=\"9\" width=\"1\" height=\"1\" fill=\"#fcc378\"/><rect x=\"19\" y=\"9\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"20\" y=\"9\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"21\" y=\"9\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"22\" y=\"9\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"23\" y=\"9\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"24\" y=\"9\" width=\"1\" height=\"1\" fill=\"#696969\"/><rect x=\"1\" y=\"10\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"2\" y=\"10\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"3\" y=\"10\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"4\" y=\"10\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"5\" y=\"10\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"6\" y=\"10\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"7\" y=\"10\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"8\" y=\"10\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"9\" y=\"10\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"11\" y=\"10\" width=\"1\" height=\"1\" fill=\"#696969\"/><rect x=\"12\" y=\"10\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"13\" y=\"10\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"14\" y=\"10\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"15\" y=\"10\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"16\" y=\"10\" width=\"1\" height=\"1\" fill=\"#8a7060\"/><rect x=\"17\" y=\"10\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"18\" y=\"10\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"19\" y=\"10\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"20\" y=\"10\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"21\" y=\"10\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"22\" y=\"10\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"23\" y=\"10\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"24\" y=\"10\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"25\" y=\"10\" width=\"1\" height=\"1\" fill=\"#8a7060\"/><rect x=\"2\" y=\"11\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"3\" y=\"11\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"4\" y=\"11\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"5\" y=\"11\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"6\" y=\"11\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"7\" y=\"11\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"8\" y=\"11\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"13\" y=\"11\" width=\"1\" height=\"1\" fill=\"#8a7060\"/><rect x=\"14\" y=\"11\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"15\" y=\"11\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"16\" y=\"11\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"17\" y=\"11\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"18\" y=\"11\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"19\" y=\"11\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"20\" y=\"11\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"21\" y=\"11\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"22\" y=\"11\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"23\" y=\"11\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"24\" y=\"11\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"25\" y=\"11\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"0\" y=\"12\" width=\"1\" height=\"1\" fill=\"#fd5d5b\"/><rect x=\"1\" y=\"12\" width=\"1\" height=\"1\" fill=\"#fcc378\"/><rect x=\"2\" y=\"12\" width=\"1\" height=\"1\" fill=\"#ffee94\"/><rect x=\"5\" y=\"12\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"6\" y=\"12\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"7\" y=\"12\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"8\" y=\"12\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"14\" y=\"12\" width=\"1\" height=\"1\" fill=\"#8a7060\"/><rect x=\"15\" y=\"12\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"16\" y=\"12\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"17\" y=\"12\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"18\" y=\"12\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"19\" y=\"12\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"20\" y=\"12\" width=\"1\" height=\"1\" fill=\"#696969\"/><rect x=\"21\" y=\"12\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"22\" y=\"12\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"23\" y=\"12\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"24\" y=\"12\" width=\"1\" height=\"1\" fill=\"#c09068\"/><rect x=\"25\" y=\"12\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"0\" y=\"13\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"1\" y=\"13\" width=\"1\" height=\"1\" fill=\"#fcc378\"/><rect x=\"2\" y=\"13\" width=\"1\" height=\"1\" fill=\"#ffee94\"/><rect x=\"3\" y=\"13\" width=\"1\" height=\"1\" fill=\"#ffee94\"/><rect x=\"4\" y=\"13\" width=\"1\" height=\"1\" fill=\"#ffee94\"/><rect x=\"14\" y=\"13\" width=\"1\" height=\"1\" fill=\"#8a7060\"/><rect x=\"15\" y=\"13\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"16\" y=\"13\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"17\" y=\"13\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"18\" y=\"13\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"19\" y=\"13\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"20\" y=\"13\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"21\" y=\"13\" width=\"1\" height=\"1\" fill=\"#873235\"/><rect x=\"22\" y=\"13\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"23\" y=\"13\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"24\" y=\"13\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"25\" y=\"13\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"1\" y=\"14\" width=\"1\" height=\"1\" fill=\"#fd5d5b\"/><rect x=\"2\" y=\"14\" width=\"1\" height=\"1\" fill=\"#fd5d5b\"/><rect x=\"3\" y=\"14\" width=\"1\" height=\"1\" fill=\"#fd5d5b\"/><rect x=\"4\" y=\"14\" width=\"1\" height=\"1\" fill=\"#fcc378\"/><rect x=\"5\" y=\"14\" width=\"1\" height=\"1\" fill=\"#ffee94\"/><rect x=\"6\" y=\"14\" width=\"1\" height=\"1\" fill=\"#ffee94\"/><rect x=\"7\" y=\"14\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"15\" y=\"14\" width=\"1\" height=\"1\" fill=\"#8a7060\"/><rect x=\"16\" y=\"14\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"17\" y=\"14\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"18\" y=\"14\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"19\" y=\"14\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"20\" y=\"14\" width=\"1\" height=\"1\" fill=\"#b87575\"/><rect x=\"21\" y=\"14\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"22\" y=\"14\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"23\" y=\"14\" width=\"1\" height=\"1\" fill=\"#0a0000\"/><rect x=\"24\" y=\"14\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"25\" y=\"14\" width=\"1\" height=\"1\" fill=\"#8a7060\"/><rect x=\"1\" y=\"15\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"4\" y=\"15\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"5\" y=\"15\" width=\"1\" height=\"1\" fill=\"#fcc378\"/><rect x=\"6\" y=\"15\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"7\" y=\"15\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"8\" y=\"15\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"16\" y=\"15\" width=\"1\" height=\"1\" fill=\"#696969\"/><rect x=\"17\" y=\"15\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"18\" y=\"15\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"19\" y=\"15\" width=\"1\" height=\"1\" fill=\"#c09068\"/><rect x=\"20\" y=\"15\" width=\"1\" height=\"1\" fill=\"#b87575\"/><rect x=\"21\" y=\"15\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"22\" y=\"15\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"23\" y=\"15\" width=\"1\" height=\"1\" fill=\"#aa6666\"/><rect x=\"24\" y=\"15\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"25\" y=\"15\" width=\"1\" height=\"1\" fill=\"#ffe2e2\"/><rect x=\"5\" y=\"16\" width=\"1\" height=\"1\" fill=\"#e5a97c\"/><rect x=\"6\" y=\"16\" width=\"1\" height=\"1\" fill=\"#ffe2e2\"/><rect x=\"7\" y=\"16\" width=\"1\" height=\"1\" fill=\"#ffe2e2\"/><rect x=\"8\" y=\"16\" width=\"1\" height=\"1\" fill=\"#ffdab0\"/><rect x=\"17\" y=\"16\" width=\"1\" height=\"1\" fill=\"#696969\"/><rect x=\"18\" y=\"16\" width=\"1\" height=\"1\" fill=\"#696969\"/><rect x=\"19\" y=\"16\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"20\" y=\"16\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"21\" y=\"16\" width=\"1\" height=\"1\" fill=\"#696969\"/><rect x=\"22\" y=\"16\" width=\"1\" height=\"1\" fill=\"#6b4535\"/><rect x=\"23\" y=\"16\" width=\"1\" height=\"1\" fill=\"#696969\"/><rect x=\"19\" y=\"17\" width=\"1\" height=\"1\" fill=\"#b87575\"/><rect x=\"20\" y=\"17\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"21\" y=\"17\" width=\"1\" height=\"1\" fill=\"#3a1510\"/><rect x=\"22\" y=\"17\" width=\"1\" height=\"1\" fill=\"#696969\"/></svg>\n      \n      Verdict: if you run LLMs in a pipeline, don’t trust the log. Open the transcript and verify which model actually worked.\n    </div>\n  </div>\n</div>\n\n<h2>What Claude Code Does with Haiku When You’re Not Looking</h2>\n\n<p>Claude Code in headless mode (<a href=\"https://github.com/anthropics/claude-code\" target=\"_blank\" rel=\"noopener\"><code>claude -p</code></a>) mixes internal models with your requested model in the same session: it runs Haiku calls for auxiliary tasks (session naming, routing) that you never asked for and don’t need. Those turns show up in the <code>.modelUsage</code> field and in the transcript ALONGSIDE your real work, with nothing to distinguish them.</p>\n\n<p>And know what that means? Any logic that checks which model responded, without filtering out those internal calls, will get it wrong. Not sometimes. ALWAYS.</p>\n\n<p>There’s more. In <code>claude -p</code>, the <code>--model</code> flag is ignored. Only the <code>ANTHROPIC_MODEL</code> environment variable works. If you don’t set it explicitly, the CLI picks a default that may be stale. And if your Max plan is close to its usage limit, <a href=\"https://docs.anthropic.com/en/docs/claude-code\" target=\"_blank\" rel=\"noopener\">Claude Code</a> silently downgrades to Haiku. No warning. No error. <code>is_error: false</code>.</p>\n\n<p>At Marketing Ultra we discovered this on June 14 while debugging our <a href=\"https://soymarketingultra.com/en/ai-content-pipeline-editorial-gate/\">AI content pipeline</a>. What came after was worse.</p>\n\n<h2>Three Broken Heuristics, Three Ways to Get Bitten</h2>\n<figure class=\"wp-block-image size-full mu-diagram\"><img src=\"https://soymarketingultra.com/wp-content/uploads/claude-code-ghost-haiku-fix-your-model-detection-diagrama.webp\" alt=\"Model detection flow diagram for Claude Code headless mode: filters out internal Haiku calls and picks the highest-output-token model as the one that actually did the work\" class=\"wp-image-2261\"/></figure>\n\n<p>We tried three methods to detect which model had actually responded. All three bit us.</p>\n\n<p><strong><code>keys[0]</code>: first model in alphabetical order.</strong> “Haiku” comes before “Opus” in the alphabet. Our heartbeat used this method. Result: it reported Haiku 24/7 for roughly 14 days. Our entire model history log, contaminated. Fourteen days of false data we didn’t catch because the pipeline was working fine. Only the record was a lie.</p>\n\n<p><strong><code>sort_by(-outputTokens)[0]</code>: the model with the most output tokens.</strong> Looks like the smart method, right? The one generating the most must be the one that did the work. Until Opus returns a short answer and the Haiku-generated title has more tokens than the real response. The log says Haiku. The work is Opus.</p>\n\n<p><strong>Exact key match against a known ID.</strong> Model IDs carry an embedded date: <code>claude-opus-4-6-20250401</code>. Our guard compared against <code>claude-opus-4-6</code> alone. No match. Exit 75: “model downgraded.” Perfect Opus work, thrown out. Several times.</p>\n\n<p>Three “obvious” heuristics. Three ways to get bitten. All from the same underlying failure: assuming <code>.modelUsage</code> only reflects YOUR work.</p>\n\n<h2>The Misdiagnosis That Cost Us 697 Seconds of Opus</h2>\n\n<p>June 19. The guard is on version 3. It reads the transcript directly. Problem solved.</p>\n\n<p>Sure about that?</p>\n\n<p>The guard grabbed the LAST assistant turn using <code>tail -1</code>. And the last turn was the title Haiku generates. The SEO Strategist had just produced a complete strategy with Opus. 697 seconds of compute. The guard looks at the transcript, sees Haiku at the end, flags <code>model_downgraded</code>.</p>\n\n<p>Eleven minutes of expensive model. Gone.</p>\n\n<p>But here’s what really pisses me off. I pull up the error log looking for a pattern. I find old entries with <code>model_downgraded</code> and a hint: “Max usage limit.” I read the error message. I assume it’s the Max plan quota running close to the cap. Makes sense, right?</p>\n\n<p>Wrong. Dani caught it by reviewing the timeline: the dates didn’t line up. Those entries weren’t real downgrades. They were false positives from earlier heuristics that had left garbage in the log. The “Max usage limit” hint was hardcoded as the default message when the guard couldn’t determine the cause.</p>\n\n<p>I read the error message instead of verifying the original transcript. And that led me to “fix” something that wasn’t broken, while ignoring what actually was.</p>\n\n<p>And this applies to EVERYTHING, not just AI: a log that says “quota exhausted” doesn’t mean the quota is exhausted. It means something wrote “quota exhausted” to the log. Verify the source data, not the derived message. ALWAYS.</p>\n\n<h2>How to Know Which Model Actually Did the Work in Claude Code</h2>\n<figure class=\"wp-block-image size-full mu-illustration\"><img src=\"https://soymarketingultra.com/wp-content/uploads/claude-code-headless-el-haiku-fantasma-que-rompe-tu-gua-ilustracion.webp\" alt=\"Quality-control inspector discards a completed Opus job over a tiny Haiku sticky note while server racks burn compute in the background — visual metaphor for ghost model contamination corrupting AI pipeline guards\" class=\"wp-image-2259\"/></figure>\n\n<p>The robust fix (v5) is simple once you understand the mechanics:</p>\n\n<ol>\n<li>Read <code>.modelUsage</code> from the transcript.</li>\n<li>Exclude ALL Haiku models. They’re internal calls, housekeeping.</li>\n<li>From what’s left, take the one with the most <code>outputTokens</code>. That’s the one that did your work.</li>\n<li>Only if ALL models are Haiku: real downgrade. Flag it.</li>\n</ol>\n\n<p>We added a permanent test that simulates a transcript with Haiku + Opus and verifies the guard reports Opus. If anyone touches the logic and breaks it, the test catches it before production. Zero trust, automatic verification.</p>\n\n<p>This applies to anyone running <a href=\"https://soymarketingultra.com/en/ai-agents-marketing/\">AI agents in real pipelines</a>: to know which model worked, never take the first, the last, or the highest token count alone. Exclude the internal calls and look only at the real work.</p>\n\n<p>If you’re running LLMs in production, asking for Opus isn’t enough. You need to verify that Opus actually responded.</p>\n\n<p>Next time your guard fires and the log tells you a story, open the transcript. Read what actually happened. This isn’t an edge case. This is what running AI seriously looks like.</p>\n\n<hr class=\"mu-faq-sep\" />\n<section class=\"mu-faq\">\n  <h2>FAQ: Claude Code Headless Mode and Model Detection</h2>\n  <h3>What is Claude Code’s headless mode (<code>claude -p</code>)?</h3>\n  <p>It’s Claude Code’s non-interactive mode, designed for pipelines and automation. You pass a prompt via stdin or as an argument, it executes and returns the result via stdout in JSON. The <code>--model</code> flag doesn’t work in this mode: the model is controlled exclusively by the <code>ANTHROPIC_MODEL</code> environment variable.</p>\n  <h3>What is <code>.modelUsage</code> in the Claude Code transcript?</h3>\n  <p>It’s a field in the JSON output that lists all models invoked during the session along with their token counts. It includes both the model that did your work and those used internally (Haiku for session naming), so it cannot be used to determine which model actually worked without filtering out the internal calls.</p>\n</section>",
 "markdown_url": "https://soymarketingultra.com/en/claude-code-headless-model-detection.md"
}