What to build
Root-cause and fix a test-isolation bug in packages/opencode's CI test run, observed while chasing unrelated CI failures on #180 (a pure-CSS PR that cannot be the cause).
Observed behavior
unit (linux)/unit (windows) CI jobs run bun test twice via turbo: a full pass first, then bun test --timeout 60000 --only-failures to retry anything that failed. In several CI runs, the second (--only-failures, presumably a smaller/isolated subset of files) invocation shows:
test/session/snapshot-tool-race.test.ts:
# Unhandled error between tests
-------------------------------
...
error: Unbound layer node: @opencode/example/LocationServiceMap
at .../packages/core/src/effect/layer-node.ts:260:48
at .../packages/opencode/test/session/snapshot-tool-race.test.ts:96:13
-------------------------------
test/session/prompt.test.ts:
...
InterruptError: All fibers interrupted without error
...
error: All fibers interrupted without error
at causeSquash (.../[email protected]/.../effect.js:171:12)
(fail) loop includes MCP instructions in model system context [20635.94ms]
snapshot-tool-race.test.ts:96 calls LayerNode.compile(root, [...]) (see the file for the exact root/replacements). packages/core/src/effect/layer-node.ts's compile() builds a fresh cache per call (not a shared/module-level cache), so the "Unbound layer node" isn't a cross-test cache collision — it means the root graph in snapshot-tool-race.test.ts genuinely resolves a dependency chain that reaches a LocationServiceMap node with kind: "unbound" that isn't satisfied by that file's root/replacements list. This only reproduces in the --only-failures isolated rerun, not the full run (1121 pass / 0 fail beforehand) — i.e. it's order/isolation-dependent, not deterministic.
The resulting unhandled async error appears to interrupt whatever test the runtime happened to be executing next (prompt.test.ts's "loop includes MCP instructions in model system context", which forks a fiber via prompt.loop(...).pipe(Effect.forkChild) and later calls yield* Fiber.interrupt(fiber) without awaiting/ignoring its exit — see line ~589). This test already has a comment documenting prior CI-load-related flakiness (bumped from 15s to 40s timeout, 2026-09-08 investigation) but this specific InterruptError failure mode is new/different (finishes at ~20s, well under the 40s budget — not a bare timeout).
Investigation needed
- Confirm why
snapshot-tool-race.test.ts's root graph is missing a binding for @opencode/example/LocationServiceMap only when run via --only-failures isolation (does something else register that node as a side effect during the full run, that isn't present when the file runs in isolation?).
- Confirm/rule out whether the unhandled error genuinely crosses file boundaries inside the same bun-test worker process, interrupting
prompt.test.ts's forked fiber — or if this is coincidental timing in the log and the two failures are unrelated.
- If (2) is confirmed, either fix
snapshot-tool-race.test.ts's layer graph so it never produces an unbound-node error, and/or harden prompt.test.ts:589's Fiber.interrupt(fiber) call (e.g. Fiber.interrupt(fiber).pipe(Effect.ignore), matching the fact the test doesn't care about that fiber's exit) so an unrelated interrupt elsewhere can't fail it.
Acceptance criteria
Blocked by
(none)
Verification
- Re-run
unit (linux)/unit (windows) CI jobs on a few consecutive PRs and confirm the specific errors above no longer appear (some general CI flakiness may remain — only this specific pair of errors is in scope)
What to build
Root-cause and fix a test-isolation bug in
packages/opencode's CI test run, observed while chasing unrelated CI failures on #180 (a pure-CSS PR that cannot be the cause).Observed behavior
unit (linux)/unit (windows)CI jobs runbun testtwice via turbo: a full pass first, thenbun test --timeout 60000 --only-failuresto retry anything that failed. In several CI runs, the second (--only-failures, presumably a smaller/isolated subset of files) invocation shows:snapshot-tool-race.test.ts:96callsLayerNode.compile(root, [...])(see the file for the exactroot/replacements).packages/core/src/effect/layer-node.ts'scompile()builds a freshcacheper call (not a shared/module-level cache), so the "Unbound layer node" isn't a cross-test cache collision — it means therootgraph insnapshot-tool-race.test.tsgenuinely resolves a dependency chain that reaches aLocationServiceMapnode withkind: "unbound"that isn't satisfied by that file'sroot/replacements list. This only reproduces in the--only-failuresisolated rerun, not the full run (1121 pass / 0 fail beforehand) — i.e. it's order/isolation-dependent, not deterministic.The resulting unhandled async error appears to interrupt whatever test the runtime happened to be executing next (
prompt.test.ts's "loop includes MCP instructions in model system context", which forks a fiber viaprompt.loop(...).pipe(Effect.forkChild)and later callsyield* Fiber.interrupt(fiber)without awaiting/ignoring its exit — see line ~589). This test already has a comment documenting prior CI-load-related flakiness (bumped from 15s to 40s timeout, 2026-09-08 investigation) but this specificInterruptErrorfailure mode is new/different (finishes at ~20s, well under the 40s budget — not a bare timeout).Investigation needed
snapshot-tool-race.test.ts'srootgraph is missing a binding for@opencode/example/LocationServiceMaponly when run via--only-failuresisolation (does something else register that node as a side effect during the full run, that isn't present when the file runs in isolation?).prompt.test.ts's forked fiber — or if this is coincidental timing in the log and the two failures are unrelated.snapshot-tool-race.test.ts's layer graph so it never produces an unbound-node error, and/or hardenprompt.test.ts:589'sFiber.interrupt(fiber)call (e.g.Fiber.interrupt(fiber).pipe(Effect.ignore), matching the fact the test doesn't care about that fiber's exit) so an unrelated interrupt elsewhere can't fail it.Acceptance criteria
bun test --timeout 60000 --only-failuresrun ofpackages/opencodeno longer produces the "Unbound layer node: @opencode/example/LocationServiceMap" error fromsnapshot-tool-race.test.tsprompt.test.tsno longer fails withInterruptError: All fibers interrupted without errorunder repeated CI runsBlocked by
(none)
Verification
unit (linux)/unit (windows)CI jobs on a few consecutive PRs and confirm the specific errors above no longer appear (some general CI flakiness may remain — only this specific pair of errors is in scope)