From 82da702f64e8f217cb1db55de10e0aa8421a595d Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Tue, 31 Mar 2026 17:32:24 -0400 Subject: [PATCH] refactor: tighten instance context helper fallbacks --- packages/opencode/src/effect/instance-state.ts | 15 +++++++++------ packages/opencode/src/effect/run-service.ts | 5 ++++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/opencode/src/effect/instance-state.ts b/packages/opencode/src/effect/instance-state.ts index ed6fd6bdc7..b073cf0a4b 100644 --- a/packages/opencode/src/effect/instance-state.ts +++ b/packages/opencode/src/effect/instance-state.ts @@ -1,5 +1,6 @@ import { Effect, Fiber, ScopedCache, Scope, ServiceMap } from "effect" import { Instance, type InstanceContext } from "@/project/instance" +import { Context } from "@/util/context" import { InstanceRef } from "./instance-ref" import { registerDisposer } from "./instance-registry" @@ -14,7 +15,9 @@ export namespace InstanceState { export const bind = any>(fn: F): F => { try { return Instance.bind(fn) - } catch {} + } catch (err) { + if (!(err instanceof Context.NotFound)) throw err + } const fiber = Fiber.getCurrent() const ctx = fiber ? ServiceMap.getReferenceUnsafe(fiber.services, InstanceRef) : undefined if (!ctx) return fn @@ -25,10 +28,7 @@ export namespace InstanceState { return (yield* InstanceRef) ?? Instance.current })() - export const directory = Effect.fnUntraced(function* () { - const ctx = yield* InstanceRef - return ctx ? ctx.directory : Instance.directory - })() + export const directory = Effect.map(context, (ctx) => ctx.directory) export const make = ( init: (ctx: InstanceContext) => Effect.Effect, @@ -74,6 +74,9 @@ export namespace InstanceState { return yield* ScopedCache.invalidate(self.cache, yield* directory) }) - /** Run a sync function with Instance ALS restored from the InstanceRef. */ + /** + * Effect finalizers run on the fiber scheduler after the original async + * boundary, so ALS reads like Instance.directory can be gone by then. + */ export const withALS = (fn: () => T) => Effect.map(context, (ctx) => Instance.restore(ctx, fn)) } diff --git a/packages/opencode/src/effect/run-service.ts b/packages/opencode/src/effect/run-service.ts index c3d96bdb00..619d5be6b5 100644 --- a/packages/opencode/src/effect/run-service.ts +++ b/packages/opencode/src/effect/run-service.ts @@ -1,6 +1,7 @@ import { Effect, Layer, ManagedRuntime } from "effect" import * as ServiceMap from "effect/ServiceMap" import { Instance } from "@/project/instance" +import { Context } from "@/util/context" import { InstanceRef } from "./instance-ref" export const memoMap = Layer.makeMemoMapUnsafe() @@ -9,7 +10,9 @@ function attach(effect: Effect.Effect): Effect.Effect try { const ctx = Instance.current return Effect.provideService(effect, InstanceRef, ctx) - } catch {} + } catch (err) { + if (!(err instanceof Context.NotFound)) throw err + } return effect }