You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Nix Desktop cannot discover its bundled CLI service #60676
The Nix Desktop build starts its bundled CLI but cannot connect to it. The backend responds to /api/info with HTTP 200 while Desktop reports Timed out waiting for the background service to start.
Nix builds the CLI with OPENCODE_CHANNEL=prod, which writes service-prod.json. Desktop probes service.json. Its build normalizes both latest and prod to the production app identity, losing the CLI channel needed for service discovery.
Desktop should discover the bundled CLI's registration and preserve existing configuration and state. Official latest builds must continue using service.json.
OpenCode version
2.2.3+122ead5
Steps to reproduce
Build opencode-desktop at jerome-benoit/opencode@122ead50368eb2d1a4a9e4617b56f9775cd4e8ce.
Launch the packaged app with isolated HOME/XDG directories.
Observe the startup timeout; the private backend is healthy and only service-prod.json exists.
Thanks for the detailed report. I reproduced the discovery mismatch from source, without building the Nix Desktop package itself:
I ran the CLI as a prod-channel build (OPENCODE_CHANNEL="prod", the same channel nix/opencode.nix uses) with serve --service and empty HOME/XDG directories. It registered only service-prod.json, and /api/info returned HTTP 200.
I then looked up the service the way Desktop does: Service.discover({ version }) with no registration file (sidecar-probe.ts, background-service.ts). It found nothing, because it only reads service.json. Pointing it at service-prod.json found the service right away.
The results are the same on v2.2.3 and on the latest dev (6700dd8). The script below reproduces it.
Related: #59403 (your Nix PR, which notes this timeout), #52121 and #52122.
Reproduction script (repro.sh)
#!/usr/bin/env bash# Reproduces #60676: a CLI built with OPENCODE_CHANNEL=prod (as nix/opencode.nix does) registers its# background service in service-prod.json, while Desktop's service lookup (Service.discover / ensure# with no `file`, as in packages/desktop/src/main/service/{sidecar-probe,background-service}.ts) only# reads service.json, so it never finds the healthy service.# Usage: REPO=/workspace/repo bash repro.shset -u
REPO=${REPO:-/workspace/repo}
ROOT=$(mktemp -d /tmp/opencode/nix-svc.XXXX)export HOME=$ROOT/home XDG_STATE_HOME=$ROOT/state XDG_CONFIG_HOME=$ROOT/config XDG_DATA_HOME=$ROOT/data XDG_CACHE_HOME=$ROOT/cache
mkdir -p "$HOME""$XDG_STATE_HOME""$XDG_CONFIG_HOME""$XDG_DATA_HOME""$XDG_CACHE_HOME""$ROOT/project"cd"$ROOT/project"# 1. Run the CLI as a channel=prod build (the same compile-time define nix/opencode.nix produces).
bun --conditions=browser \
--define 'OPENCODE_CHANNEL="prod"' --define 'OPENCODE_VERSION="2.2.3"' \
--preload="$REPO/packages/tui/node_modules/@opentui/solid/scripts/preload.js" \
"$REPO/packages/cli/src/index.ts" serve --service >"$ROOT/serve.log"2>&1&
PID=$!foriin$(seq 1 60);do ls "$XDG_STATE_HOME"/opencode/service*.json >/dev/null 2>&1&&break; sleep 1;done
sleep 2
echo"== registration files in \$XDG_STATE_HOME/opencode =="
ls "$XDG_STATE_HOME/opencode"| grep -i service
REG=$(ls "$XDG_STATE_HOME"/opencode/service*.json | head -1)
URL=$(bun -e "console.log(JSON.parse(require('fs').readFileSync('$REG','utf8')).url)")
PW=$(bun -e "console.log(JSON.parse(require('fs').readFileSync('$REG','utf8')).password ?? '')")echo"== backend health ($URL/api/info) =="
curl -s -o /dev/null -w "HTTP %{http_code}\n" -u "opencode:$PW""$URL/api/info"# 2. Look the service up exactly as Desktop does (no explicit registration file).
cat >"$REPO/packages/desktop/.repro-discover.ts"<<'EOF'import { Service } from "@opencode/client/service"const found = await Service.discover({ version: "2.2.3" })console.log("Desktop-style Service.discover() ->", found ?? "undefined (service not found)")const withFile = await Service.discover({ version: "2.2.3", file: process.argv[2] })console.log("Service.discover({ file: service-prod.json }) ->", withFile?.url ?? "undefined")EOFecho"== Desktop-style discovery =="
(cd "$REPO/packages/desktop"&& bun .repro-discover.ts "$REG")
rm -f "$REPO/packages/desktop/.repro-discover.ts"kill$PID2>/dev/null;wait$PID2>/dev/null
pkill -f "$ROOT"2>/dev/null
Activity
opencodejr commentedon Oct 30, 2026
Thanks for the detailed report. I reproduced the discovery mismatch from source, without building the Nix Desktop package itself:
prod-channel build (OPENCODE_CHANNEL="prod", the same channelnix/opencode.nixuses) withserve --serviceand empty HOME/XDG directories. It registered onlyservice-prod.json, and/api/inforeturned HTTP 200.Service.discover({ version })with no registration file (sidecar-probe.ts,background-service.ts). It found nothing, because it only readsservice.json. Pointing it atservice-prod.jsonfound the service right away.The results are the same on
v2.2.3and on the latestdev(6700dd8). The script below reproduces it.Related: #59403 (your Nix PR, which notes this timeout), #52121 and #52122.
Reproduction script (repro.sh)
Run it:
bash repro.shchore(upstream-fixes): track the two opencode-desktop workarounds