Skip to content

Desktop: white screens & send failures from corrupted global state JSON, stale session.path, dangling server refs (1.18.3, Windows + WSL) #37353

Description

Description

Environment: Desktop 1.18.3 (Electron, ai.opencode.desktop) on Windows 11, server running as WSL sidecar (Ubuntu-24.04, opencode server 1.18.1, WSL2 mirrored networking). CLI 1.17.18 also installed. Two separate databases exist: Windows (%USERPROFILE%.local\share\opencode\opencode.db) and WSL (~/.local/share/opencode/opencode.db).

Over ~9 days the desktop app degraded through: white screen at launch (Session not found, 404) → sessions browsable but sending fails ("cannot get session") → white screen on server switch (Session not found, different id) → white screen after deleting a custom server (Notification server not found: http://localhost:4097).

Root causes identified (evidence in the attached full report + debug log bundle):

  1. Global state file corrupted by an unescaped newline (most severe). opencode.global.dat had an error message (stack trace containing raw \n) written unescaped into a JSON string. The whole file then failed to parse ("Bad control character in string literal"), every store-get/store-set threw, and all stateful UI operations — including sending messages — broke. The file mtime froze on the day of corruption: UI state silently failed to persist for 9 days. Suggest validating/escaping on serialize, and on parse/write failure backing up + resetting the file instead of failing forever.

  2. Event-sourced projection rows deleted without events. 18 sessions had intact event logs (up to 46k events) but missing session/message/part projection rows; no session.deleted event exists anywhere in the DB. Restoring "last session" then 404s and white-screens. Suggest a db repair/rebuild-projections command and writing tombstone events on delete.

  3. Stale absolute paths in session.path. Sessions moved between directories keep absolute paths (legacy convention; current is '' for project-root sessions). The server joins worktree+path → realPath NotFound → "cannot get session" on send. Present in both DBs. Suggest normalizing on write plus a cleanup migration.

  4. No fallback for dangling references. "Last session" / home.selection / tabs pointers are stored per server and trusted blindly; when the pointed session or server is gone (the two DBs' session sets had diverged), the renderer throws Session not found / Notification server not found and white-screens instead of ignoring the stale pointer and falling back to a default view.

  5. WSL sidecar accepts Windows-path workspaces. Creating a C:/ workspace on a WSL connection makes the server realPath('C:/') → ENOENT, the event stream dies, chat is impossible. Suggest validating path reachability per server type, or auto-translating to /mnt/c/....

  6. Custom server entry cannot be deleted when state-file writes fail (bug 1) and tabs/selection still reference it. Needs cascade cleanup (tabs/selection/notification/workspace bindings) plus a conflict prompt.

  7. (Minor, already healed in 1.18.3) A July desktop build called SessionContextEpoch.requestReplacement referencing column replacement_seq, which its own bundled migration (20260622142730_simplify_session_context_epoch) had already dropped → runtime "no such column". Flagging as a release-consistency check suggestion.

User-side repair (completed; app fully usable again): replayed event logs to rebuild projections, fixed stale paths in both DBs, repaired the state file via lenient parse + canonical re-serialization, merged the Windows DB into the WSL DB with path translation (C:/→/mnt/c/, E:/→/mnt/e/, D:/→/mnt/d/), and removed the dead server entry with all its references. Full step-by-step write-up with evidence attached.


### Plugins

_No response_

### OpenCode version

Desktop 1.18.3 (Electron 42.3.3); WSL server/sidecar 1.18.1; CLI 1.17.18 

### Steps to reproduce

1. State file corruption: insert an unescaped raw newline inside a string value in %APPDATA%\ai.opencode.desktop\opencode.global.dat (simulating an unescaped error message) → launch the desktop app → renderer throws "Bad control character in string literal" on every store-set; UI state never persists; sending messages fails.
2. Dangling last-session pointer: with "last session" = session X in server A's DB only, switch to server B whose DB lacks session X → white screen "Session not found: X". Similarly, delete a custom server still referenced by home.selection → restart → white screen "Notification server not found".
3. Stale path: have a session row whose session.path is an absolute path of a since-deleted directory (e.g. moved project) → open the session (browsable) → send a message → server joins worktree+path, realPath fails → "cannot get session".
4. WSL workspace: connect to a WSL server, create a workspace at C:/ (any Windows path) → server logs PlatformError NotFound realPath, event stream disconnects, cannot chat.

(Item 2 in Description — missing projections — was observed on live data; we do not know which build deleted the rows. The event logs are intact and contain no tombstone events.)

### Screenshot and/or share link

[opencode-bug-report-20260717-en.md](https://github.com/user-attachments/files/30098091/opencode-bug-report-20260717-en.md)

[opencode-debug-20260716T155136.zip](https://github.com/user-attachments/files/30098110/opencode-debug-20260716T155136.zip)

### Operating System

Windows 11 (desktop); Ubuntu-24.04 via WSL2 mirrored networking (server) 

### Terminal

Desktop app (Electron); Windows Terminal for CLI usage

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions