anomalyco / anomalyco/opencode
tui: V1 custom themes silently fall back to default theme (converter requires new color keys)
@simonklee is already working on this.
Since Aug 23, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Summary
Custom themes created for OpenCode 1 (flat V1 theme JSON files in ~/.config/opencode/themes/) are silently ignored by OpenCode 2: the TUI always renders the default opencode theme with no error or warning. The V1→V2 theme converter throws on a handful of newer color keys that V1-era themes don't define, and the TUI's fallback swallows the error.
Per the V1→V2 migration guide, existing V1 configuration (including themes) is intended to remain compatible, so this is a compatibility regression.
Environment
- opencode version: 0.0.0-beta-17941 (
opencode2) - OS: Windows 10 Pro 22H2 (10.0.19045 x64)
- Terminal: Windows Terminal / conhost (xterm-256color)
- Shell: Git Bash (MINGW64) / cmd.exe
- Install/channel: beta
- Active plugins: local plugin
~/.config/opencode/plugin/model-fallback.ts(unrelated to theming)
Reproduction
-
Create a minimal V1-style theme at
~/.config/opencode/themes/test.json:{ "$schema": "https://opencode.ai/theme.json", "theme": { "text": "#0032a0", "textMuted": "#5a7ac0", "background": "#ffffff", "backgroundPanel": "#f2f5ff", "backgroundElement": "#e6ecff", "border": "#b0c0e8", "borderActive": "#0032a0", "borderSubtle": "#d0daf0", "primary": "#0032a0", "secondary": "#5a7ac0", "accent": "#0032a0", "error": "#da291c", "warning": "#da291c", "success": "#0032a0", "info": "#0032a0", "diffAdded": "#0032a0", "diffRemoved": "#da291c", "diffContext": "#0032a0", "diffHunkHeader": "#0032a0", "diffAddedBg": "#eef4ff", "diffRemovedBg": "#ffefee", "diffContextBg": "#f2f5ff", "diffLineNumber": "#b0c0e8", "markdownText": "#0032a0", "markdownHeading": "#da291c", "markdownLink": "#0032a0", "markdownLinkText": "#0032a0", "markdownCode": "#da291c", "markdownBlockQuote": "#5a7ac0", "markdownEmph": "#da291c", "markdownStrong": "#da291c", "markdownListItem": "#0032a0", "markdownCodeBlock": "#da291c", "syntaxComment": "#5a7ac0", "syntaxKeyword": "#da291c", "syntaxFunction": "#0032a0", "syntaxVariable": "#0032a0", "syntaxString": "#da291c", "syntaxNumber": "#da291c", "syntaxType": "#0032a0", "syntaxOperator": "#da291c", "syntaxPunctuation": "#0032a0" } }This is the complete classic V1 key set — it worked fine in OpenCode 1.
-
Set
"theme": { "name": "test" }in~/.config/opencode/cli.json. -
Start
opencode2.
Expected Behavior
The test theme is applied (white background, blue foreground), matching OpenCode 1 behavior and the migration guide's compatibility guarantee.
Actual Behavior
The default opencode dark theme is rendered instead. There is no warning in ~/.local/share/opencode/log/opencode.log, no toast, nothing indicating the theme failed.
Verified experimentally by capturing TUI render output: with a built-in theme (dracula, tokyonight) the expected background colors appear in the ANSI stream; with any of my six V1 custom themes they never do — both global (~/.config/opencode/themes/) and project-local (.opencode/themes/) discovery locations were tested.
Root cause (from inspecting the bundled code in opencode2.exe)
The V1→V2 theme converter builds the new token set by reading these legacy keys directly:
diffHighlightAdded,diffHighlightRemoveddiffAddedLineNumberBg,diffRemovedLineNumberBgmarkdownHorizontalRule,markdownListEnumeration,markdownImage,markdownImageText
e.g. diff.highlight.added = D(e["diffHighlightAdded"]) where D() calls .toInts(). For a V1 theme that doesn't define these keys this throws TypeError: Cannot read properties of undefined. The throw happens inside the resolved-theme memo:
try { return QP(Ln.themes[M], M, Ln.mode) }
catch (j) {
if (M === "opencode") throw j;
JP.emit(M, j); // only surfaces as a toast inside the theme picker
Pi("active", "opencode"); // silent permanent fallback
...
}
So any V1 theme missing even one of the new keys is permanently rejected and the UI silently falls back to opencode.
Workaround
Adding the eight missing keys (any sensible colors derived from the theme palette) makes the theme load again. After adding them, all of my previously broken V1 themes apply correctly. The converter should instead treat these keys as optional and derive defaults from existing colors (e.g. reuse diffAddedBg/diffRemovedBg and markdownLink/markdownListItem).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.