[MODEL] Fable5 - Silent downgrade to Opus

Open 💬 0 comments Opened Jul 12, 2026 by SilentGhostline

Preflight Checklist

  • [x] I have searched existing issues for similar behavior reports
  • [x] This report does NOT contain sensitive information (API keys, passwords, etc.)

Type of Behavior Issue

Other unexpected behavior

What You Asked Claude to Do

What You Asked Claude to Do:

I am part of Anthropic's Cyber Use-case Program (CVP) — our organization (ID e82d769a-e717-4e48-a5ed-289e0b7f3931) is approved for authorized dual-use security work (exploit development, offensive tooling, penetration testing) under that program.

I asked Claude Code to orchestrate autonomous offensive-security sub-agents (via the Agent tool) to solve HackTheBox machines and CTF challenges under this CVP authorization — killchains from recon through privilege escalation, and standalone CTF challenge solving (reversing, pwn, crypto, web, forensics). For our hardest/longest-reasoning tasks (HTB Hard/Insane-difficulty machines, complex multi-stage exploit chains), I explicitly requested the sub-agents run on the Fable model (model: "fable" in the Agent tool call / agent definition), since it's our top-reasoning-tier model chosen specifically for its strength on long, hard, multi-step chains.

While investigating why one such sub-agent (working an HTB "Hard" machine) received an unexpected policy/safety refusal, I asked Claude to check the raw session transcript — which is when I discovered the agent had also silently fallen back from Fable to Opus 4.8 partway through, with no notification. That prompted me to ask Claude to audit every historical sub-agent run in our project where Fable had been explicitly requested, to determine how widespread the issue was. Claude greped 33 such runs across 6 separate Claude Code sessions (multiple days) and found 100% of them (33/33) had silently fallen back to Opus within the first few messages, with only ~2% of total generated messages actually run on Fable across the whole dataset — confirmed reproducible live by killing and relaunching an affected agent, which fell back again immediately.

What Claude Actually Did

Instead of running the requested sub-agent tasks on Fable as configured, Claude Code silently substituted Opus 4.8 for the vast majority of the work — without ever surfacing this to me as the operator.

Concretely: within the first 1–4 assistant messages of a Fable-launched sub-agent's session, an internal fallback event fires — {"type":"fallback","from":{"model":"claude-fable-5"},"to":{"model":"claude-opus-4-8"}} — logged only inside the raw JSONL message stream, not exposed through any notification, warning, error state, or status field visible to the orchestrating session. The sub-agent's own spawn metadata (*.meta.json) continued to report "model":"fable" throughout, so from every outward signal I had, the task appeared to be running on Fable as requested; it wasn't.

Auditing 33 historical sub-agent runs (6 separate Claude Code sessions, multiple days) where Fable was explicitly requested, all 33 (100%) exhibited this silent fallback. Of ~3,474 total messages generated across those runs, only ~68 (~2%) actually ran on Fable — the other ~98% ran on Opus while every visible signal said Fable. I reproduced it live as well: killing an affected agent and relaunching it fresh with identical configuration triggered the same fallback again, immediately, on the very next launch.

The practical effect is that a deliberate, security-relevant model choice (Fable, selected specifically for its stronger reasoning on our hardest reverse-engineering/exploit-development tasks) was silently overridden every single time, with no way to detect it short of manually grepping raw transcript files for the string "model": — something no operator would think to do routinely, since nothing indicates the substitution occurred.

fable_downgrade_evidence.zip

Expected Behavior

  1. Run on the requested model, full stop. If a sub-agent is explicitly configured with model: "fable", it should execute on Fable for its entire session unless there is a genuine, documented reason it cannot (e.g. sustained unavailability) — and even then, silent substitution should not be the default.
  2. If a fallback is unavoidable, surface it immediately and explicitly to the orchestrator. This should work the same way policy/safety refusals already do — via a clear signal equivalent to the existing idle_notification / failureReason mechanism — so the operator can decide in real time whether to accept the substitute model, retry, or abort, instead of the substitution happening invisibly mid-session.
  3. Reflect reality in the metadata. The sub-agent's spawn metadata (*.meta.json or equivalent) should show the model that actually executed the session (or a clear mixed-model flag), not just the originally requested model — so that even a post-hoc audit doesn't require parsing the raw transcript.

None of these happened. The task ran almost entirely on a different, silently-substituted model, with the configuration record and every operator-visible signal continuing to claim otherwise — for a security-sensitive workflow where the model choice was deliberate, not incidental.

fable_downgrade_evidence.zip

Files Affected

Attached: fable_downgrade_evidence.zip

Contains the raw evidence for all 34 affected sub-agent runs referenced in this report: for each agent, its .jsonl transcript (containing the per-message "model": field and the {"type":"fallback",...} marker) and its matching .meta.json spawn metadata (showing the originally-requested "model":"fable"), preserved under their original <session_uuid>/subagents/ folder structure across 6 Claude Code sessions.

To verify: grep -c '"model":"claude-fable-5"' vs grep -c '"model":"claude-opus-4-8"' on any .jsonl in the archive reproduces the per-run counts in the report's table; grep -o '"type":"fallback"[^}]*}[^}]*}' surfaces the explicit fallback marker in every single one.

Permission Mode

Accept Edits was ON (auto-accepting changes)

Can You Reproduce This?

Yes, every time with the same prompt

Steps to Reproduce

Can You Reproduce This? Does this happen consistently?

Yes — 100% reproduction rate, every time, no exceptions found.

All 34 audited sub-agent runs where Fable was explicitly requested (across 6 separate Claude Code sessions, spanning multiple days) showed the fallback — zero clean runs. Beyond the historical audit, I reproduced it live twice more today in real time: killed an affected agent mid-task and relaunched it fresh with identical configuration — the fallback fired again within the first couple of messages both times.

It is not intermittent, not tied to a specific machine/task/day, and not something that resolves on retry.

  1. In Claude Code, invoke the Agent tool (or a custom sub-agent definition) with an explicit model assignment of fable (e.g. model: "fable" in the tool call, or a custom agent type whose definition frontmatter sets model: fable).
  2. Give it any non-trivial, multi-step task (in our case: autonomous offensive-security work — an HTB machine killchain or CTF challenge, but the task content itself does not appear to matter).
  3. Let the sub-agent run normally — no error is shown, no refusal, no visible sign anything is wrong. It appears to complete its task successfully.
  4. After the agent finishes (or at any point during the run), inspect its raw transcript file: ~/.claude/projects/<project>/<session_uuid>/subagents/agent-a<name>-<hash>.jsonl.
  5. Run: grep -o '"model":"claude-[^"]*"' <transcript>.jsonl | sort | uniq -c — this will show the actual model(s) that generated each message.
  6. Run: grep -o '"type":"fallback"[^}]}[^}]}' <transcript>.jsonl — this surfaces the explicit fallback marker.
  7. Observe: within the first 1-4 assistant messages, a {"type":"fallback","from":{"model":"claude-fable-5"},"to":{"model":"claude-opus-4-8"}} entry appears, and essentially all subsequent messages show "model":"claude-opus-4-8" instead of "claude-fable-5".
  8. For comparison, check the corresponding agent-a<name>-<hash>.meta.json spawn metadata file — it still reports "model":"fable", with nothing indicating the divergence from step 7.
  9. To confirm it's not a one-off: kill the affected agent and relaunch a fresh one with identical configuration (same model, same task). The fallback reproduces again, immediately, on the new session.

We repeated steps 1-9 across 34 independent sub-agent launches (6 different Claude Code sessions, multiple days) and observed the fallback in all 34 (100%).

Claude Model

Other

Relevant Conversation

Impact

Critical - Data loss or corrupted project

Claude Code Version

Claude Code v2.1.207

Platform

Anthropic API

Additional Context

_No response_

View original on GitHub ↗