diff --git a/packages/opencode/src/cli/cmd/tui/worker.ts b/packages/opencode/src/cli/cmd/tui/worker.ts index 0b61dd45d83..7af891141b1 100644 --- a/packages/opencode/src/cli/cmd/tui/worker.ts +++ b/packages/opencode/src/cli/cmd/tui/worker.ts @@ -140,10 +140,14 @@ export const rpc = { await Promise.race([ Instance.disposeAll(), new Promise((resolve) => { - setTimeout(resolve, 5000) + setTimeout(resolve, 5000).unref() }), ]) if (server) server.stop(true) + // Clear the Rpc message channel so the worker's event loop can drain and + // exit naturally. Without this, the active onmessage handle keeps the + // worker alive even after all async work is done. + onmessage = null }, }