Workflow fan-out inherits a premium-tier default with no per-agent cost ceiling, causing ~$1k in auto-purchased charges
EDIT 2026-06-13 (correction, see comments): The original "malformed model ID / ANSI escape leak" root cause below is wrong. A byte-level check of the affectedsettings.jsonshows zero ESC (0x1b) bytes;[1m]is the legitimate context-tier suffix, not a leaked escape. The model family is decided by the prefix before[1m], soopus[1m]could never resolve to Fable 5. The persisted default wasclaude-fable-5[1m](already thefable-5family), and the runtime ran exactly that. The real, preventable cause is a premium-tier default inherited by a 700+ agent Workflow fan-out with no per-agent model ceiling and no spend gate, with auto-purchase firing without ever surfacing the tier-times-fan-out cost. Billing figures are also corrected in the comments (three card charges totaling $800 usage / $864 with tax, not two). Invoice IDs removed; they live in the support ticket. Original text left intact below for thread continuity.
---
Bug report and billing impact
This is a companion to #68279 (the /model picker bug report). Filing separately because the billing impact warrants its own tracking.
The bug
The /model picker writes a malformed model ID to ~/.claude/settings.json. Instead of a clean ID like claude-opus-4-8[1m], it persists opus[1m] where [1m] is a raw ANSI SGR bold escape sequence leaking from terminal rendering into the serialized JSON value.
- Deterministic and reproducible (triggered 3x consecutively on 2026-06-13, v2.1.177)
- The picker reports success even when it writes a corrupt value
- No settings validation catches the bad ID
- The bad ID silently resolves to a different (premium) model tier at runtime
Financial impact
On 2026-06-11, the corrupted setting (claude-fable-5[1m]) caused a Workflow to spawn 700+ subagents on Fable 5 (the most expensive tier, $10/$50 per MTok) instead of the intended Sonnet ($3/$15). In under 2 hours:
- ~$350 in pre-purchased usage credits consumed
- $200 auto-purchased and charged to card
- $400 auto-purchased and charged to card
- A third $200 auto-purchase the following day (corrected total: $800 usage, $864 with tax across three charges)
- Included Max plan allocation for the billing window consumed (75% of $1,100 limit from one day)
- Total bug-driven excess: ~$1k (receipted card floor $864; true token burn higher, in the usage console)
The spend limit was hit 3 times, which also corrupted the workflow results (partial verdicts, false "dry round" signals from killed agents).
Root cause chain
/modelpicker writes malformed ID to settings.json (ANSI escape leak)- Malformed ID silently resolves to Fable 5 (premium tier) at runtime
Workflowsubagents inherit the default model from settings.json- 700+ agents run on Fable 5 instead of the intended cheaper model
- Spend limit hit repeatedly, auto-triggering prepaid credit purchases
- User has no visibility into the corrupted setting until manually inspecting the JSON file
Evidence
- GitHub issue #68279 (the reproduction)
- Auto-purchase receipts (in the open support ticket)
- Git commit
b37c6a8in claude-config repo documenting the fix - Session handoffs documenting the incident contemporaneously
- Post-incident rule file (
ultracode-model-routing.md) documenting root cause
Environment
- Claude Code 2.1.177
- macOS 15.2 (Darwin 25.5.0)
- Shell: zsh
- Max plan (20x)
What should happen
- The
/modelpicker should not leak ANSI escape sequences into persisted JSON - Settings validation should reject malformed model IDs on write
- At runtime, an unrecognized model ID should error rather than silently resolving to a premium tier
- The spend-limit mechanism should not auto-purchase credits without explicit user consent when the overage is caused by a system-side defect
This issue has 7 comments on GitHub. Read the full discussion on GitHub ↗