Custom theme overrides ignored in startup banner title (borderText pre-coloured with base theme)

Resolved 💬 2 comments Opened Jun 6, 2026 by HaydenReeve Closed Jul 12, 2026

Environment: Claude Code v2.1.167 (native install), Windows 11 Pro (build 26200), Windows Terminal, "theme": "custom:<slug>" in ~/.claude/settings.json

Summary

When a custom theme (~/.claude/themes/<slug>.json) is active, every live UI element honours its overrides — except the startup banner's title text ("Claude Code") and version string, which render with the base theme's colours (claude = terracotta rgb(215,119,87), inactive = rgb(153,153,153) for base: "dark"). The banner border around them honours the override, producing a visibly mismatched header.

Repro

  1. Create ~/.claude/themes/bugtest.json:

``json
{
"name": "Bug Test",
"base": "dark",
"overrides": {
"claude": "#00FF00",
"claudeShimmer": "#00FF00"
}
}
``

  1. Set ~/.claude/settings.json: { "theme": "custom:bugtest" }
  2. Launch claude in any terminal.

Expected: banner title and version use the custom theme's resolved claude/inactive values, matching the border.
Actual: the banner border is green; the words "Claude Code" inside it are terracotta.

Deterministic evidence

ConPTY capture of a v2.1.167 startup under an isolated CLAUDE_CONFIG_DIR with the theme above (escape characters shown as \e):

\e[38;2;0;255;0m╭───\e[6G\e[38;2;215;119;87mClaude Code\e[18G\e[38;2;153;153;153mv2.1.167\e[27G\e[38;2;0;255;0m────╮
  • border ╭───: 38;2;0;255;0 — the override, honoured
  • title Claude Code: 38;2;215;119;87 — built-in dark claude, override discarded
  • version v2.1.167: 38;2;153;153;153 — built-in dark inactive
  • the green override appears 21× elsewhere in the same frame; the banner title/version are the only claude/inactive elements not using it

Root cause (from the v2.1.167 bundle)

The banner title is a pre-coloured string passed as borderText.content, built via (identifiers minified):

b = Cu(u1("theme", "dark").value)                       // theme NAME resolution
m = ` ${T$("claude", b)("Claude Code")} ${T$("inactive", b)(`v${J}`)} `
B = { borderColor: "claude", borderText: { content: m, ... } }   // borderColor resolves correctly

Cu() resolves custom:<slug> through the custom-theme registry, but that registry maps slug → base name only (A16.set(q.slug, q.base)), so Cu("custom:bugtest") returns "dark" and T$ colours the string from the built-in dark palette — the custom overrides are silently discarded.

Ink-side color:"claude" props resolve through the live theme with overrides applied, which is why only the pre-coloured borderText strings regress.

---

![✨ Issue created by Claude CLI](https://claude.com/claude-code)

View original on GitHub ↗

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