Repository navigation
Description
tui: one invalid cli.json field silently discards the entire config
Summary
A single invalid field in ~/.config/opencode/cli.json causes OpenCode to silently
drop the whole file. No error is shown; every setting (sidebar, cursor, theme,
keybinds, …) falls back to defaults. This is very hard to diagnose because there is
no user-visible signal that validation failed.
Environment
- opencode version: 2.0.32 (release / latest, single binary)
- OS: Linux 7.1.8-arch1-3 x86_64 (Arch)
- Terminal: xterm-256color (also reproduced under tmux 3.7b / tmux-256color); occurs both inside and outside tmux
- Shell: /usr/bin/bash
- Install/channel: release,
latest - Active plugins: none configured (only built-in
opencode.sidebar.*plugins)
Reproduction
-
Create
~/.config/opencode/cli.jsoncontaining a valid setting plus one invalid
field — e.g. a top-levelleadergiven as a string (the V1tui.jsonshape):{ "$schema": "https://opencode.ai/v2/cli.json", "leader": "ctrl+x", "session": { "sidebar": "hide" }, "cursor": { "style": "line", "blinking": false } } -
Launch the TUI (
opencode). -
Observe that the sidebar is still visible and the cursor is a block, and that
custom keybinds are ignored.
Expected Behavior
Either the config is applied, or OpenCode surfaces a visible error/warning naming the
invalid field (and ideally still applies the valid parts).
Actual Behavior
The entire cli.json is discarded and every setting reverts to defaults. No error is
shown to the user. The only way to notice is by observing that settings silently do
nothing.
Confirmed by inspecting the emitted terminal escape sequences: with the file above the
TUI emits a blinking block cursor (ESC [ 1 SPACE q); a minimal valid file emits
the steady line cursor (ESC [ 6 SPACE q). Bisecting field-by-field isolates
top-level leader as the trigger.
Additional Context
- The top-level
leaderschema expects an object ({ "timeout": <int> }); it is not
the leader key. The leader key belongs atkeybinds.leader. A string value fails
schema validation and invalidates the whole document. - Source:
packages/opencode/src/config/tui.ts→ on validation failure the loader runs
Effect.logWarning("skipping invalid tui config", …)and returns{}. That warning is
not surfaced in the TUI, so the failure is invisible to the user. - Workaround: move the value to
keybinds.leader(and/or drop the invalid key). The file
then loads correctly. - Impact: high discoverability cost; users assume the feature is broken (e.g. "sidebar
won't hide", "cursor won't change") when in fact their config was never read.
Suggested Fix
Surface a visible warning when cli.json fails validation (e.g. a transient TUI notice
or a line in /debug), and/or report the offending key path, rather than silently
discarding the entire file.
Activity
opencode-agent commentedon Oct 17, 2026
Thanks for the detailed report. I was able to reproduce this on 2.0.32, and it still happens on the latest
dev(bc5fa1c).Steps:
cli.jsonwithsession.sidebar: "hide", acursorsetting, and a top-level"leader": "ctrl+x".leaderline and start again. The sidebar is hidden as configured.The recording and screenshots below show both runs, and the script below reproduces it.
The v2 loader validates
cli.jsonas a whole and falls back to empty settings if any field is invalid, without telling you. Your workaround (moving the leader key tokeybinds.leader) is the right one for now.Related:
opencode.json. That PR makes it visible on stderr but doesn't covercli.jsonor add an in-TUI notice.recording.mp4
Reproduction script (drive.ts)
Run it with opencode-drive:
opencode-drive run ./drive.ts. It drivesopencodefrom yourPATH; setOC_DEVto the path of an OpenCode checkout to run that from source instead.