anomalyco / anomalyco/opencode
tui: one malformed custom theme file silently disables all custom themes
@kommander is already working on this.
Since Aug 22, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Description
A single invalid themes/*.json file anywhere in the discovered .opencode directories disables every custom theme, not just the invalid one.
In packages/tui/src/context/theme.tsx, discoverThemes() parses each matched file with JSON.parse and no per-file error handling, so the first malformed file rejects the whole discovery pass. The rejection is then swallowed in syncCustomThemes() via catch(() => setStore("active", "opencode")): nothing is logged, previously working themes disappear from the picker, and the active theme silently resets to the default.
This diverges from the convention the tui config loader itself documents ("every broken-config path degrades gracefully rather than crashing" - see packages/opencode/src/config/tui.ts), where an unreadable or invalid file is skipped with a warning while the remaining valid files still apply.
Suggested direction: isolate each file's parse, skip and warn on failure instead of failing the entire batch.
Steps to reproduce
- Create a valid custom theme at
.opencode/themes/my-theme.json, select it in the TUI - works. - Add a second file
.opencode/themes/broken.jsonwhose content is just{(invalid JSON). - Restart the TUI (or trigger a theme refresh).
- Both custom themes are now gone from the theme list and the active theme has silently fallen back to
opencode. Fixingbroken.jsonbrings everything back.
Operating System
Windows 11 (the logic is platform-independent)
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.