Repository navigation
[Windows][OpenCode 2] MC 0.44.0 hangs opencode serve at boot: /health never answers, supervisor kill/restart loop #554
Description
Short description
On Windows, MC 0.44.0 hangs opencode serve at boot: the process stays alive but /health never answers, so an external supervisor kills it after ~20 failed health checks and restarts it — endless restart loop. Pinning @0.43.2 boots cleanly on the same machine and binary, so the regression is in 0.44.0.
What happened?
Environment: OpenChamber (Electron app) manages a headless opencode server: opencode.exe serve --hostname 127.0.0.1 --port <p> (opencode v2.0.18, Windows 11 x64). OpenChamber health-checks http://127.0.0.1:<p>/health every 15 s and kills + restarts the server after ~20 consecutive timeouts.
Timeline (2026-09-28, local time UTC+2):
- 13:54 —
@cortexkit/opencode-magic-context@0.44.0published to npm (registry:2026-09-28T11:54:58Z). - 14:02 / 14:09 — servers still booted normally (MC RPC listening, commands registered).
- 14:21 — first hung boot. MC log:
SQLite boot busy timeout: backend=Bun timeout=5000ms, then a cascade ofanother Magic Context RPC server is active for this project (pid …, port …); starting separate instance on a new port— several new listeners within the same second, from different pids (stale instances of previous kill/restart cycles probing each other). - 14:23 onward — supervisor log fills with
periodic health check failed (1/20) class=timeout…(18/20), thenprocess exited, restarting..., and the pattern repeats. 17 restarts over ~5 hours. - The stderr of the hung processes shows MC itself loads (including the
protected_tags is deprecated and ignoredwarning) — the plugin gets that far, then the boot stalls. The process never crashes and never prints an error. - 19:09 — plugin entry commented out as a rescue → server boots and stays healthy (without MC).
- 19:37 — pinned
@cortexkit/opencode-magic-context@0.43.2in the global config and re-enabled → boots cleanly,/healthreturns HTTP 200, no further restarts. Also verified in an isolatedopencode serveon a test port with the same bundled binary: 0.43.2 loads, single RPC listener,/health200 within ~2 s.
Expected: opencode serve with MC 0.44.0 boots and answers /health within seconds, like 0.43.2 does.
Observed: process alive (no crash, no exit code, no error output) but HTTP never comes up; only the supervisor's kill breaks the state — and then the next boot hangs the same way.
Repro
- Windows 11 x64, opencode v2.0.18, headless
opencode serve. - Global plugin config:
"@cortexkit/opencode-magic-context@latest"(resolves 0.44.0). - Start the server → process stays alive,
/healthtimes out indefinitely. - Pin
@0.43.2, restart → healthy in seconds.
Analysis (hypothesis, grounded in the 0.44.0 code path behind #553)
- The migration guard in
openDatabase/openDatabaseAsynccallsinspectRpcServerDiscovery()+inspectLivePiProcesses(). On Windows these runpowershell(CIMWin32_Processquery,WINDOWS_CIM_PROBE_TIMEOUT_MS = 5_000) andtasklistviaexecFileSync— synchronous, event-loop-blocking, withoutwindowsHide(the same spawn sites confirmed for [Windows][OpenCode 2] Magic Context repeatedly opens PowerShell and CMD windows that steal focus #553). - New in 0.44.0 (OpenCode V2: every turn refused in silence with 0.43.2 — v2 refuseIfUnsafe / "context storage is not durable" (outcome=interrupted, no assistant message) #546):
v2/hooks/storage-gate.tsretries a refused DB open every 5 s (V2_STORAGE_REOPEN_INTERVAL_MS = 5_000), and each retry re-runs the synchronous Windows probes. - Under the supervisor's rapid kill/restart cycles, several MC instances probe each other (see the "another Magic Context RPC server is active" cascade — one new listener per attempt), and the synchronous probes block the event loop long enough that the HTTP server never gets to answer
/health→ kill → restart → loop. - The MC log shows the stall happens around DB open, before the v91 migration lane:
upstream migration lane at boot: database=v90, supported_fence=v90— the DB never reached fence 91 during the loop, which is also why downgrading to 0.43.2 was still possible here.
Happy to run doctor --issue non-interactively if there's a flag for it — the interactive wizard doesn't complete in a headless shell, so the diagnostics below are filled in manually per the template.
Diagnostics
- Plugin version: 0.44.0 (
npm dist-tags.latest, published 2026-09-28T11:54:58Z) - OpenCode version: 2.0.18 (bundled CLI of OpenChamber)
- Platform: Windows 11 x64
- Client: OpenChamber-managed headless opencode server (
opencode serve) - Config: plugin spec
@latestin globalopencode.jsonc;protected_tags: 15present. The deprecation warning appears on stderr in both healthy (0.43.2) and hung (0.44.0) boots, so it is not the cause.
Log output
Supervisor (OpenChamber) log — one full kill/restart cycle; this pattern repeats ~every 5 minutes for hours:
[14:23:55] [lifecycle] periodic health check failed (1/20) class=timeout
[16:50:12] [lifecycle] periodic health check failed (4/20) class=timeout
[16:50:27] [lifecycle] periodic health check failed (5/20) class=timeout
... (15 s interval)
[16:54:57] [lifecycle] periodic health check failed (18/20) class=timeout
[16:55:11] [lifecycle] periodic health check: OpenCode process exited, restarting...
[16:56:51] [lifecycle] periodic health check failed (1/20) class=timeout ← loop restarts
MC log at the hung boot (sanitized; %TEMP%\opencode2\magic-context\magic-context.log):
[14:21:47] [magic-context] SQLite boot busy timeout: backend=Bun timeout=5000ms path=~\.local\share\cortexkit\magic-context\context.db
[14:21:47] [magic-context] upstream migration lane at boot: database=v90, supported_fence=v90
[14:21:47] [magic-context][global] models-dev-cache: API layer loaded 96 model metadata entries
[14:21:47] [magic-context] registered server-side commands: ctx-status ctx-recomp ctx-dream ctx-flush ctx-embed ctx-wrapup
[14:21:48] [rpc] another Magic Context RPC server is active for this project (pid 100136, port 49564); starting separate instance on a new port
[14:21:48] [rpc] server listening on 127.0.0.1:62756
[14:21:48] [rpc] another Magic Context RPC server is active for this project (pid 59276, port 60121); starting separate instance on a new port
[14:21:49] [rpc] server listening on 127.0.0.1:62766
[14:21:49] [rpc] another Magic Context RPC server is active for this project (pid 12976, port 57412); starting separate instance on a new port
[14:21:50] [rpc] server listening on 127.0.0.1:62801
... (one additional listener every ~400 ms, multiple pids from earlier restart cycles)
With @0.43.2 pinned, same machine, same binary: single RPC listener, /health HTTP 200 within ~2 s, zero health-check failures since.
Workaround
Pin @cortexkit/opencode-magic-context@0.43.2 and restart all hosts sharing the DB. Note for anyone hitting this: the stall happens before the v91 migration runs, so downgrading stays safe — but once 0.44.0 has completed the v91 migration on a DB, 0.43.2 will refuse it (fence 90 vs 91), so pin before the first successful 0.44.0 boot.
Activity
magic-alfonso commentedon Sep 28, 2026
Thanks for the detailed report, and for trying the pin and the isolated check. We're investigating.
Your analysis matches code that changed in 0.44.0: on Windows, the storage check runs
powershellandtasklistsynchronously, and 0.44.0 added a storage-open retry every 5 seconds that repeats those checks. The fix for #553 already hides those windows. For this issue we're making the checks asynchronous and bounded, and making sure the server always comes up no matter what state Magic Context's storage is in. We're reproducing it on a real OpenCode 2.0.18 host with Windows-like conditions first.One detail we'd like to understand: the log line you quote from the hung boot says
supported_fence=v90, and 0.44.0 would printv91there. So that line came from a 0.43.x build. OpenCode 2 keeps its cached@latestinstall until it's updated, so more than one plugin version may have been running across the restarts. If you still have themagic-context.logfrom a hung boot, could you share the lines that containsupported_fence,storage, orrefus, with their timestamps? And do you know whether more than oneopencode.exeor OpenChamber instance was running at the time?Your workaround (pin
@0.43.2before 0.44.x completes its first boot) is correct, and your note about the migration order is right too. Note that 0.44.1, released today, doesn't include a fix for this yet, so keep the pin until we post here.morpheus9393 commentedon Sep 29, 2026
Thanks for the pointer — you were right to question the version, and after re-checking I owe you a correction: 0.44.0 was never installed on this host. The hung processes were running 0.43.2 all along.
Cache proof that
@latestnever picked up 0.44.0The OpenCode package cache has exactly one Magic Context install root (
...\packages\@cortexkit\opencode-magic-context@latest), untouched since 2026-09-25 14:45 local — three days before the 0.44.0 publish:No second install directory exists, and nothing in it was modified on 2026-09-28. So on this host the
@latestspec resolved once (→ 0.43.2, on 09-25) and never re-resolved to 0.44.0 after the publish at 2026-09-28 09:54Z — consistent with the "cache resolves@latestexactly once and never refreshes" behavior we had already observed on this setup. My original report's causal chain (publish → re-resolve → 0.44.0 boots → hang) did not happen.Requested
magic-context.loglines (supported_fence/storage/refus)All
supported_fencelines in the log, ever (the log starts 2026-09-25), showdatabase=v90, supported_fence=v90. There is nov91line anywhere, including inside the hang windows on 09-28. Lines during/around the hang period (UTC):There are no storage-
refus*lines at all in the log (the onlyrefushits are unrelated dreamer curation-safety refusals). So the DB never got near a migration, and no storage gate ever refused — as you predicted, thev90line I originally quoted was from a 0.43.x build; in fact every line was.Context on the
SQLite boot busy timeoutlines: they are chronic on this host, not specific to the hang day — 6 on 09-25, 15 on 09-26, 7 on 09-27, 6 on 09-28, i.e. roughly once per boot on calm days too, and the boot proceeds normally after them.Your multi-instance question: yes, many
Every new instance that shares a project logs the RPC cascade. Distinct
opencode.exePIDs seen in that cascade on 09-28 alone: 19232, 100136, 16352, 44096, 104912, 100880, 12976, 44144, 100184, 102904, 59276 (11+ concurrent hosts on a typical day — one OpenChamber-managed server plus several user-launched session hosts). Some persisted across the whole day. Example from a boot inside the hang window:What the supervisor log actually shows
Daily count of
periodic health check failedlines in the OpenChamber supervisor log:So the kill/restart storm is recurring and version-independent — it also happened on 09-24/09-25 with pre-0.43.2 builds, was calm on 09-26/09-27 with the same 0.43.2, and stormed again on 09-28 with the same 0.43.2. On 09-28 the first health failure followed a sleep/wake signature by 4 seconds:
Restart diagnostics from a hung instance (process alive,
/healthnever answering; stderr tail trimmed to the Magic Context line — full tail also contains unrelated plugin warnings):(
net::ERR_NETWORK_IO_SUSPENDEDoccurs ~3x/day here on every day including calm ones, so it alone isn't the trigger, but the 4-second proximity to the storm onset on 09-28 is notable.)Revised picture
Given all of the above, the original attribution in this issue — "0.44.0's new synchronous storage probes hang the boot" — does not hold for this host: the storm predates 0.44.0's publish on 09-24/09-25, and the 09-28 storm ran entirely on 0.43.2. What we can say from the evidence: the managed
opencode serveprocess stops answering/health(event-loop-level block or deadlock, process alive with exitCode null) with Magic Context loaded, under an environment with many concurrent Magic-Context-hosting instances and a contendedcontext.db, and it has happened across multiple MC versions. Whether Magic Context is causal (e.g., a boot path that blocks on the busy DB/lock while 10+ hosts contend) or merely present, we can't tell from these logs alone.Two questions from our side:
context.dbis contended by many concurrent hosts (e.g. the 5000ms busy timeout path retrying synchronously, or the RPC single-instance probe)?@latestcache genuinely never re-resolves (our observation, twice now), the upgrade path to the fixed 0.44.x will be "delete the@latestinstall root or change the spec to an explicit pin" — might be worth calling out in the release notes for [Windows][OpenCode 2] Magic Context repeatedly opens PowerShell and CMD windows that steal focus #553/[Windows][OpenCode 2] MC 0.44.0 hangs opencode serve at boot: /health never answers, supervisor kill/restart loop #554-adjacent fixes.For now we're staying pinned to
@0.43.2(still working; the 09-28 storm ended after the pin plus removal of stale instances, though per the above we can't attribute the recovery to the pin specifically). Happy to run instrumented tests on an isolated port with a fixed build if that helps.release notes: v0.44.2 dreamer, search and #554 status
magic-alfonso commentedon Sep 29, 2026
0.44.2 is now on npm with the part of this we could reproduce: OpenCode 2 keeps answering
/healthwhile Magic Context's storage opens. The process checks before opening the database are asynchronous and time-limited, so a supervisor no longer sees the server stall at boot.The restart storms you described on 0.43.2, with many OpenCode instances sharing one database, are still under investigation, so I'm leaving this open. If you're pinned to 0.43.2: 0.44.2 migrates a v90 database to v91 on first start, after which 0.43.x refuses it, so upgrade every host that shares the database.
magic-alfonso commentedon Sep 29, 2026
0.44.3 includes the refined busy-database handling. A turn now waits up to 250 ms for a lock held by another OpenCode instance, and background writes give up after 25 ms and retry on their next run, so a brief lock no longer refuses turns and a long one no longer stalls the host. With 11 OpenCode 2 instances sharing one
context.dbunder a 10-second held write lock, every/healthprobe was answered. Leaving this open until you can confirm whether the restart loops you saw stop on 0.44.3.magic-alfonso commentedon Oct 17, 2026
Checking in: are you still seeing the
/healthrestart loops on 0.49.10 with several OpenCode instances sharing one database? Since 0.44.3, a turn waits briefly for a lock held by another instance and background writes back off, and 0.49.6 extended that wait to 2 seconds. If the loops have stopped, we'll close this.