Description
v1.4.8 deadlocks when plugins call client.app.log() during initialization. The TUI renders but never shows the active model.
Plugins
Any plugin using client.app.log() during initialization
OpenCode version
1.4.8, 1.4.9
Steps to reproduce
- Save the following as
~/.config/opencode/plugins/my-plugin.ts:
import type { Plugin, PluginModule } from "@opencode-ai/plugin"
const server: Plugin = async ({ client }) => {
await client.app.log({
body: { service: "my-plugin", level: "warn", message: "hello" },
})
return {}
}
export default { id: "my-plugin", server } satisfies PluginModule
- Start opencode
- TUI renders but hangs before showing the active model
Screenshot and/or share link
No response
Operating System
Arch Linux (irrelevant)
Terminal
Alacritty (irrelevant)
Root Cause
v1.4.8 moved InstanceMiddleware before ControlPlaneRoutes in packages/opencode/src/server/server.ts:
// v1.4.8 (broken)
app: app
.use(InstanceMiddleware())
.route("/", ControlPlaneRoutes())
...
// v1.4.7 (working)
app: app
.route("/", ControlPlaneRoutes())
.route("/", InstanceRoutes(runtime.upgradeWebSocket))
...
InstanceMiddleware calls Instance.provide({ init: InstanceBootstrap }) on every request. InstanceBootstrap calls Plugin.init(), which loads all plugins. The deadlock:
InstanceMiddleware runs InstanceBootstrap → Plugin.init() → plugin server() runs
- Plugin calls
client.app.log() → in-process fetch to Hono
- Hono routes the request through
InstanceMiddleware again
Instance.provide() awaits the same bootstrap promise from step 1
- Deadlock: step 4 waits for step 1, which waits for step 2, which waits for step 4
Possibly related: #23103, which may be the same deadlock triggered by a different code path through InstanceMiddleware.
Description
v1.4.8 deadlocks when plugins call
client.app.log()during initialization. The TUI renders but never shows the active model.Plugins
Any plugin using
client.app.log()during initializationOpenCode version
1.4.8, 1.4.9
Steps to reproduce
~/.config/opencode/plugins/my-plugin.ts:Screenshot and/or share link
No response
Operating System
Arch Linux (irrelevant)
Terminal
Alacritty (irrelevant)
Root Cause
v1.4.8 moved
InstanceMiddlewarebeforeControlPlaneRoutesinpackages/opencode/src/server/server.ts:InstanceMiddlewarecallsInstance.provide({ init: InstanceBootstrap })on every request.InstanceBootstrapcallsPlugin.init(), which loads all plugins. The deadlock:InstanceMiddlewarerunsInstanceBootstrap→Plugin.init()→ pluginserver()runsclient.app.log()→ in-process fetch to HonoInstanceMiddlewareagainInstance.provide()awaits the same bootstrap promise from step 1Possibly related: #23103, which may be the same deadlock triggered by a different code path through
InstanceMiddleware.