/model picker writes malformed model ID to settings.json

Open 💬 2 comments Opened Jun 13, 2026 by joshduffy

Bug

The /model picker writes a malformed model ID to ~/.claude/settings.json. Instead of a clean model ID like claude-opus-4-8[1m], it persists opus[1m] where [1m] is an ANSI bold escape sequence leaking from the terminal UI into the JSON value.

Repro

  1. Open Claude Code (2.1.177, macOS, zsh)
  2. Run /model
  3. Select "Opus 4.8 (1M context)" (or any model)
  4. Observe the terminal output: Set model to **Opus 4.6 (1M context)** (bold formatting visible)
  5. Check the persisted value: grep '"model"' ~/.claude/settings.json

Expected: "model": "claude-opus-4-8[1m]"
Actual: "model": "opus[1m]"

Details

  • The [1m] suffix is the ANSI SGR bold sequence (\e[1m), not the 1M context window qualifier. Something in the serialization path captures the raw escape code instead of stripping it before writing to JSON.
  • The bug is deterministic. Selecting the same model three consecutive times produces the same malformed value each time.
  • The UI also reports the wrong model name ("Opus 4.6") when "Opus 4.8" was selected, suggesting the display name mapping may also be off, or the picker is selecting the wrong entry.
  • The [1m] in the persisted value happens to look like a valid context-window suffix, so it doesn't cause a parse error. Instead it silently resolves to a different (potentially more expensive) model or falls back unpredictably.

Impact

  • Users get silently pinned to the wrong model with no visible error.
  • Subagents and workflows inherit the malformed default via settings.json, which can cause unexpected cost if the fallback resolution is a premium tier.

Workaround

Edit ~/.claude/settings.json directly:

"model": "claude-opus-4-8[1m]",

Environment

  • Claude Code 2.1.177
  • macOS 15.2 (Darwin 25.5.0)
  • Shell: zsh
  • Terminal: likely relevant since ANSI escapes are involved

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗