Skip to content

Commit cb9322e

Browse files
fix(core): return the saved fork when a plugin hook fails
1 parent 0566efd commit cb9322e

2 files changed

Lines changed: 28 additions & 1 deletion

File tree

‎packages/core/src/session.ts‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,10 @@ const layer = Layer.effect(
386386
yield* Plugin.awaitActivation
387387
const hooks = yield* PluginHooks.Service
388388
yield* hooks.trigger("session", "fork", { sessionID })
389-
}).pipe(instances.provide(forked), Effect.orDie)
389+
}).pipe(
390+
instances.provide(forked),
391+
Effect.catchCause((cause) => Effect.logWarning("fork hook failed", { sessionID, cause })),
392+
)
390393
return forked
391394
}),
392395
get: (sessionID) => sessions.forSession(sessionID).get(),

‎packages/sdk/test/instances.test.ts‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,30 @@ test("Promise instances are lazy, share by key and Location, and stay isolated b
145145
expect(cleanups.toSorted()).toEqual(setups.toSorted())
146146
}, 20_000)
147147

148+
test("a throwing fork hook still returns the saved fork", async () => {
149+
await using directory = await tmpdir("opencode-fork-hook-")
150+
const seen: string[] = []
151+
await using host = await OpenCode.create({
152+
...hostOptions(directory.path),
153+
plugins: [
154+
{
155+
id: "broken-fork-hook",
156+
async setup(ctx) {
157+
await ctx.session.hook("fork", ({ sessionID }) => {
158+
seen.push(sessionID)
159+
throw new Error("fork hook failed")
160+
})
161+
},
162+
},
163+
],
164+
})
165+
const parent = await host.sessions.create({ location: { directory: directory.path } })
166+
await host.sessions.switchAgent({ sessionID: parent.id, agent: "plan" })
167+
const fork = await host.sessions.fork({ sessionID: parent.id })
168+
expect(seen).toEqual([fork.id])
169+
expect(await host.sessions.get({ sessionID: fork.id })).toMatchObject({ id: fork.id, fork: { sessionID: parent.id } })
170+
})
171+
148172
test.each(["configuration", "plugin setup"])(
149173
"Promise instance %s failure admits nothing, preserves healthy instances, and can be retried",
150174
async (failure) => {

0 commit comments

Comments
 (0)