Skip to content

OpenCode Desktop v1.17.14 can get stuck in an infinite startup crash loop with: Error: Notification server not found: http://[server-ip]:4096 #35686

Closed

Description

@jones

Description

Bug

OpenCode Desktop v1.17.14 can get stuck in an infinite startup crash loop with: Error: Notification server not found: http://[server-ip]:4096

The error appears shortly after app startup, and there is no way to clear it from the UI. Restart and Reload Webview do not fix it; the same error comes back on the next launch.

What Happened

I encountered this after a hard crash on macOS 27.0 beta. The entire macOS UI froze, so I had to hard reset the computer.

After rebooting, OpenCode Desktop was stuck in this state whenever I opened it. The IP address in the error is an OpenCode server on my local network, and I can connect to that server normally outside of this crash loop.

Expected Behavior

OpenCode Desktop should not crash during startup because notification state is missing for a server key.

If notification state cannot be found for the active server, the app should continue loading and treat notifications for that server as empty/unavailable.

Actual Behavior

https://i.imgur.com/PrzmNdu.png

The renderer crashes during app startup with:

Error: Notification server not found: http://[server-ip]:4096
    at ensure (oc://renderer/assets/main-B1osgIPb.js:85602:24)
    at selected (oc://renderer/assets/main-B1osgIPb.js:85634:28)
    at Object.unseenCount (oc://renderer/assets/main-B1osgIPb.js:85648:37)
    at oc://renderer/assets/main-B1osgIPb.js:109261:107
    at Array.reduce (<anonymous>)
    at Object.fn (oc://renderer/assets/main-B1osgIPb.js:109261:47)
    at runComputation (oc://renderer/assets/main-B1osgIPb.js:487:22)
    at updateComputation (oc://renderer/assets/main-B1osgIPb.js:470:3)
    at Object.readSignal (oc://renderer/assets/main-B1osgIPb.js:403:67)
    at Object.fn (oc://renderer/assets/main-B1osgIPb.js:109269:72)
    at runComputation (oc://renderer/assets/main-B1osgIPb.js:487:22)
    at updateComputation (oc://renderer/assets/main-B1osgIPb.js:470:3)
    at createMemo (oc://renderer/assets/main-B1osgIPb.js:119:3)
    at ProjectIcon (oc://renderer/assets/main-B1osgIPb.js:109269:18)

This leaves the app unusable.

Debugging Notes

The crash appears to come from a stale/missing server key reaching the notification context.

At render time, a project icon asks for unseen notification count:

ProjectIcon
  -> notification.project.unseenCount(directory)
  -> selected()
  -> ensure(activeServer())

The relevant source path appears to be:

packages/app/src/pages/layout/sidebar-items.tsx
  ProjectIcon renders unseen notification count

packages/app/src/context/notification.tsx
  selected() calls ensure(activeServer())
  ensure() looks up the active server key in global.servers.list()

The failing condition is:

active server key: http://[server-ip]:4096
current server list: sidecar only

So notification lookup tries to resolve:

http://[server-ip]:4096

but the active runtime server list does not contain a connection with that key. It only contains the desktop sidecar connection.

The current behavior is fatal:

const conn = global.servers.list().find((item) => ServerConnection.key(item) === key)
if (!conn) throw new Error(`Notification server not found: ${key}`)

Because this throw happens during a Solid reactive render path, the renderer crashes. On reload, the app restores the same persisted/default state, reaches the same render path, and crashes again. That creates the infinite loop.

Suspected State Mismatch

From debugging the local state, this looked like a mismatch between persisted/default server identity and the runtime server list.

The stale key came from the configured/default remote server:

defaultServerUrl = http://[server-ip]:4096

But on desktop startup, the available runtime server list contained the local sidecar connection rather than a direct connection keyed by that remote URL.

After the hard macOS reset, persisted state still referenced the remote server key in project/session state, but the server list no longer had a corresponding server entry. That made notification state lookup fail during initial rendering.

The likely shape was:

server.key / active notification key:
  http://[server-ip]:4096

global.servers.list():
  sidecar

persisted project/session state:
  references http://[server-ip]:4096

Why This Is Fatal

The missing server only affects notification badge state, but the exception is thrown synchronously while rendering the app shell/sidebar. That means a cosmetic notification lookup can crash the whole desktop renderer.

Expected fallback behavior for this path would be something like:

ready: false
session notifications: []
project notifications: []
unseen counts: 0
markViewed: no-op

That would preserve debuggability while preventing the renderer from crashing.

Temporary fix

I was able to clear the error temporarily by deleting opencode.global.dat. However, the error returned after I opened the app and connected to the server again.

I was able to stop the crash loop by removing the saved defaultServerUrl value from the OpenCode Desktop settings/config, so the app no longer started with the stale remote server key.

Environment

  • OpenCode Desktop: v1.17.14
  • macOS: 27.0 beta
  • Server: OpenCode server on local network at http://[server-ip]:4096

Screenshot

https://i.imgur.com/PrzmNdu.png

Plugins

None

OpenCode version

v1.17.14

Steps to reproduce

  1. Configure OpenCode Desktop v1.17.14 with defaultServerUrl pointing to a remote/local-network OpenCode server, for example http://[server-ip]:4096.

  2. Have persisted desktop state that references that server key in project/session state, but where the server list no longer contains a matching server entry.

  3. Launch OpenCode Desktop.

  4. The app attempts to render project/session notification badges during startup.

  5. The renderer crashes with:

Error: Notification server not found: http://[server-ip]:4096

Screenshot and/or share link

https://i.imgur.com/PrzmNdu.png

Operating System

MacOS 27 Beta. Version 27.0.0: Mon Jun 15 22:59:49 PDT 2026; root:xnu-13432.0.5.501.1~2/RELEASE_ARM64_T6020 arm64

Terminal

N/A, this is the opencode desktop app

Activity

  1. github-actions commented on Jul 7, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

  2. Meepo268 commented on Jul 9, 2026

    @Meepo268

    我在win11上遇到了同样的问题,解决办法是指定 默认服务器。

  3. Edison-A-N commented on Jul 10, 2026

    @Edison-A-N

    Reproduced on v1.17.18 (Linux server + remote Desktop client)

    Same crash, same stack trace, different port and slightly newer version. Adding my data point to confirm this is not fixed in v1.17.14 → v1.17.18 (3 releases span).

    Environment

    OpenCode v1.17.18 (Desktop client)
    Server opencode serve --port 10013 --hostname 0.0.0.0 on Linux (x86_64)
    Desktop Remote Desktop client connecting to the Linux server over LAN
    Deploy defaultServerUrl → http://<server-ip>:10013
    OS (server) Linux
    OS (desktop) (remote machine, Desktop app)

    Stack trace (identical failure path)

    Error: Notification server not found: http://<server-ip>:10013/
        at ensure (oc://renderer/assets/main-CoCn6xBf.js:85829:24)
        at selected (oc://renderer/assets/main-CoCn6xBf.js:85861:28)
        at Object.unseenCount (oc://renderer/assets/main-CoCn6xBf.js:85875:37)
        at oc://renderer/assets/main-CoCn6xBf.js:110886:107
        at Array.reduce (<anonymous>)
        at Object.fn (oc://renderer/assets/main-CoCn6xBf.js:110886:47)
        ...
        at ProjectIcon (oc://renderer/assets/main-CoCn6xBf.js:110894:18)
    

    Same ProjectIcon → unseenCount → ensure() → throw → SolidJS reactive crash.

    Observations from the server side

    On the server, opencode serve is healthy and listening:

    LISTEN  0.0.0.0:10013  →  opencode (pid=2952394)
    GET /   →  401   # root path requires auth, this is expected
    

    The server returns 401 on the root path (auth required), but the Desktop renderer treats the notification lookup failure as a fatal throw inside the Solid reactive render path, freezing the entire UI — not just the notification badge.

    Impact

    • UI completely freezes; no interaction possible.
    • Restarting the Desktop app does not help — same crash on next launch (same persisted state, same render path).
    • Server side is fine; only the Desktop renderer is affected.

    Expected behavior (same as original report)

    A missing/stale notification server entry should degrade gracefully to unseenCount = 0 instead of throwing synchronously inside the render path. The notification subsystem should never be able to crash the app shell.

    Workaround that worked for me

    Removing the persisted defaultServerUrl / clearing opencode.global.dat on the Desktop side (same as the original report).

    Note

    This reproduces without a hard OS crash on the Desktop side — simply connecting a remote Desktop client to a LAN opencode serve instance can trigger it when the persisted server key does not match the runtime server list. The bug is latent in the normal remote-server deploy, not only post-crash recovery.

  4. Edison-A-N commented on Jul 10, 2026

    @Edison-A-N

    Update: server auth removed, Desktop still crashes — confirms root cause is persisted state mismatch, not auth

    After removing server-side authentication (verified GET / and notification endpoint both return 200), the Desktop renderer still crashes with the identical error. This confirms the root cause described in the original report: the crash is caused by a persisted state mismatch in opencode.global.dat, not by a server-side auth/connection failure.

    What is opencode.global.dat

    It is the Desktop client's binary persisted global state file, stored locally on the Desktop machine (not on the server). It persists:

    State Description
    global.servers.list() Known server connection list (keyed by URL)
    defaultServerUrl Default server URL to connect on launch
    project/session state References server keys
    notification state Unseen counts etc.

    Why deleting it temporarily fixes the crash

    The bug is a mismatch between persisted state and runtime server list:

    Persisted in opencode.global.dat:
      active server key = http://<server-ip>:10013/
    
    Runtime server list (on Desktop startup):
      local sidecar only — does not contain the remote server key
    

    On every Desktop launch → reads opencode.global.dat → restores activeServer = http://<server-ip>:10013/ → ProjectIcon renders → calls unseenCount → ensure(activeServer) searches global.servers.list() → key not found → throw new Error("Notification server not found: ...") → SolidJS reactive render path crashes → entire UI freezes.

    Deleting opencode.global.dat = clear all persisted state → Desktop starts fresh → no stale server key → no throw → UI loads normally.

    But it recurs

    As the original reporter noted, the fix is temporary: once you reconnect to the remote server from Desktop, the server key gets written back into opencode.global.dat. On the next launch, if the runtime server list again does not contain that key, the crash returns. This creates a reproducible crash loop on every cold start for the remote-server deploy pattern.

    Confirmed diagnosis

    This is not an edge case from an OS hard crash. It reproduces in a standard deploy:

    • Server: opencode serve --port 10013 --hostname 0.0.0.0 (Linux, healthy, returns 200)
    • Desktop: remote client connecting over LAN
    • Trigger: persisted defaultServerUrl / server key in opencode.global.dat does not match the runtime server list on next startup

    The fatal code path remains:

    const conn = global.servers.list().find((item) => ServerConnection.key(item) === key)
    if (!conn) throw new Error(`Notification server not found: ${key}`)

    A missing notification server entry should degrade to unseenCount = 0 (no-op fallback), not throw synchronously inside the SolidJS reactive render path and freeze the entire application.

  5. Bilge commented on Jul 16, 2026

    @Bilge

    I have no defaultServerUrl, so I have no temporary workaround.

  6. opencode-agent commented on Jul 20, 2026

    @opencode-agent
    Contributor

    Fixed by #37890.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions