Repository navigation
Description
Draft — GitHub issue for anomalyco/opencode
Title: SSE /api/event fibers interrupted mid-turn by provider/model config reload triggered from other connected directories (v2.0.26, Windows)
Environment
- opencode: v2.0.26 (
@opencode/clivia npm global, Bun runtime) on Windows 11 - Architecture: one shared background server on a fixed port, serving multiple clients via
?directory=workspaces (6 distinct directories connected concurrently) - Providers: default + one custom OpenAI-compatible provider with a 16-model whitelist (relevant because config reloads are frequent)
Summary
When provider/model configuration is reloaded on the shared server — apparently triggered by clients connecting from other directories — in-flight SSE streams on /api/event for unrelated, active sessions are torn down with InterruptError: All fibers interrupted without error. The HTTP response itself completes with status 200, but the event stream simply stops mid-turn. CLI clients running opencode run --format json then exit silently (no terminal event), which downstream tools interpret as a crash and retry.
Observed behavior (2026-10-10, all times UTC)
Server log (~/.local/share/opencode/log/opencode.log) shows bursts of:
timestamp=2026-10-10T07:00:16.095Z level=INFO run=bf476822 cause="InterruptError: All fibers interrupted without error\n at ServerProcess.start (B:/~BUN/root/chunk-gn3byahv.js:2:7477)..." http.span=15810 http.method=GET http.url=/api/event http.status=200
- 22 such interrupts between 06:4x and 07:0x on one hour alone.
- Each affected GET
/api/eventhas a largehttp.span(e.g. 15810 ms) and still returnshttp.status=200— the interruption happens while the SSE response is streaming. - The server process does not restart (stable PID across the whole window, 19 active connections) — this is not a watchdog/service-replacement issue.
Correlation on the client side (a desktop tool spawning opencode run --format json --session <id> per task):
cli starting ... args=["run","--format","json","--dangerously-skip-permissions","--model","...","--session","ses_edb74a31dffedlcMIDfbjAJjWZ"]
followed by no further output (silent death). The same session was resumed 16 times between 06:41 and 07:00 — each resume starting a fresh CLI that again hit an interrupted stream — burning tokens each time.
The server log in the same period is dominated by config-churn events (provider:updated etc., on the order of 1300+ events/day across the connected directories), consistent with ScopedCache invalidation racing in-flight request fibers.
Impact
- Any multi-client setup where one workspace's config reload can kill unrelated active streams.
- Silent CLI exit gives callers no usable error to distinguish "stream interrupted" from "model/provider failure", causing retry storms in wrapping tools.
Suspected mechanism
Same class as #32755 (ScopedCache invalidation → instance disposal interrupts all in-flight lookup fibers): a provider/model config reload — here triggered by other ?directory= clients connecting/reconnecting — disposes shared instances and interrupts fibers of in-flight SSE requests, including /api/event streams for sessions in unrelated directories. Differs from #52049 / #51216 in that the server is not restarted/replaced; differs from #48907 in that no skill loading is involved.
Minimal reproduction sketch
- Start shared server, connect client A with directory DA and an active long-running session streaming
/api/event. - From client B (directory DB), trigger provider config reload (e.g. connect/reconnect, or touch provider config).
- Observe A's
/api/eventstream terminate withInterruptError ... http.status=200and the CLI exit without a terminal event.
Secondary observation (Windows-specific)
~38 occurrences of unhandled rejections like:
EPERM: operation not permitted, rename '...session.json.<pid>.<uuid>.tmp' -> '...session.json'
when multiple processes write shared session state concurrently — suggests atomic-rename on shared state files needs retry/serialization under Windows.
Related issues
- bug: InterruptError — All fibers interrupted when InstanceStore.dispose races with Agent.list #32755 — same InterruptError mechanism (CLOSED, but clearly still reproducible)
- Skill tool fails with "All fibers interrupted without error" on Windows #48907 — same error, skill-loading trigger
- cli(win): 45s event-stream idle watchdog restarts the managed service, aborting all sessions/subagents #52049, desktop(win): background service SIGKILLed mid-turn when snapshot capture blocks /api/info for >6s -> ~60s restart loop, aborted turns #51216 — service replacement/SIGKILL restart loops (different trigger: server actually restarts there; here it does not)
Activity
opencode-agent commentedon Oct 10, 2026
Thanks for the detailed report! Before we try to reproduce it, could you describe briefly, in your own words, what you did, what you expected and what you saw? A lot of the current text is analysis and guesswork. Specifically, it would help to have:
opencode run --format json --session <id> ...in directory A, then do what from directory B (connect a client? edit the provider config?), and does A's run stop every time?--print-logsadded.provider:updated/ config reload entries right before the interrupt, so the link between the two can be seen.One note: the
InterruptError ... GET /api/event ... http.status=200lines at INFO level are written whenever an event-stream request ends by being interrupted, and that can also happen when the client closes the stream. So on their own they may be a result of the CLI exiting rather than its cause. That's why the steps and the CLI's own output matter here.You can reply here with the details, or edit the issue. If you edit it, please also leave a comment saying you've updated it, so we know you're done.
Related issues I found, ordered by likelihood of being relevant:
InterruptError, caused by instance disposal racing an in-flight lookup (closed)opencode runexiting silently with no errorEPERMrename onsession.json, which matches your secondary observationopencode-agent commentedon Oct 13, 2026
We're closing this for now because we haven't heard back. To check whether a provider/model config reload from another directory really interrupts unrelated
/api/eventstreams, we need a few things: steps you've confirmed reproduce it, the exit code, stderr and--print-logsoutput from oneopencode runthat exited silently, and the server log lines around that moment. Without them, theInterruptError ... http.status=200lines could just as well come from the client closing the stream.If you can share those details, please reply here or open a new issue with them, and we'll take another look. The Windows
EPERMrename problem you mentioned is already tracked in #51470. Thanks for the report!