You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
EXPERIMENTAL_BACKGROUND_SUBAGENTS: hidden sessions created inside ephemeral subagent processes can never be deleted at runtime (owner is undefined, the DELETE is never even attempted) #594
With OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true, OpenCode 2 spawns short-lived opencode processes for background subagents. These processes load Magic Context like any other opencode process. Hidden sessions created by the plugin running inside them record no owner, so they can never be deleted at runtime — by design of the owner-bound route, not by any transient failure.
What happened?
Every opencode process loads the configured plugins — we observed plugin boot logs from short-lived app: "cli" processes spawned for background subagents (four boots within one second during a batch). When the plugin inside such a process creates a hidden child:
hostServiceOwner() only returns a value when the creating process registered a service. Ephemeral subagent processes never register, so child.owner is undefined.
On retire, resolveOwnerHostService(undefined) throws HostServiceUnavailable ("created by an OpenCode host that registered no service, so there is no owner-bound route to delete it through") before any HTTP request is made.
The failure is caught and logged as "left for a later sweep" — but the sweep hits the same gate, so runtime retries can never succeed. The plugin's own output says the only cleanup is doctor --fix with OpenCode closed.
Supporting observation: an ephemeral process booted at 01:33:47 observed the parent session idle at 01:34:24.524, and a batch of dreamer hidden sessions was created at 01:34:24.558 (34 ms later) — consistent with the plugin in the ephemeral process firing the due dream run.
Structurally, the creating process is gone by the time anyone could retry, so no owner-bound route can ever exist for these children — even on hosts where deletion otherwise works (e.g. OpenChamber attached to a registered service instance). This lane leaks one visible root session per hidden run until an offline doctor --fix pass, and on plain-serve hosts it adds to the pile from #589.
Suggestion
On retire, if the current process created the child and no owner-bound service route exists, attempt the delete while the process is still alive, through its own credentials: process.env.OPENCODE_PASSWORD (or the legacy OPENCODE_SERVER_PASSWORD) plus the hostname/port from process.argv (serve --hostname <h> --port <p>). Hosts that inject the password (OpenChamber does — it sets OPENCODE_PASSWORD on the managed instance) would then clean up at retire time. That same fallback also fixes the plain-serve case in #589. The fully general fix remains an in-process session remove in the plugin host API (anomalyco/opencode#49389).
Diagnostics
Affected children have no owner recorded; retirement logs "cannot be deleted: no owner-bound host removal route; run doctor --fix with OpenCode closed".
Thanks, that's an accurate trace. A child created inside a short-lived background-subagent process has no owner-bound route, so neither runtime retries nor the sweep can ever delete it.
We'd rather not build the password-and-port fallback. The real fix has landed upstream: anomalyco/opencode#49389 is merged on OpenCode's v2 branch. It gives plugins in-process session.remove, and it lets session.create set a parent, so children are deleted together with their parent.
We're building on that now. Each hidden run becomes a child of the session that triggered it, and it's removed in-process when the run finishes, so the creating process doesn't need a registered service. It works the same inside ephemeral subagent processes.
It needs an OpenCode 2 release newer than 2.0.21, which doesn't include it yet. Once that release ships, we'll require it and remove the current workarounds. Until then, doctor --fix with OpenCode closed is the cleanup. I'll post here when it ships.
Fixed in 0.45.0, now on npm. On OpenCode 2.0.22 and newer, Magic Context creates its background sessions under your session and deletes them through OpenCode's own session API, so nothing reads credentials from the environment. Sessions earlier versions left behind are deleted in small batches at startup.
To update, quit every OpenCode and Pi process first: the database migrates on first start, which can take up to a minute on a large database. OpenCode 1 and Pi pick up the new version on restart. On OpenCode 2 (2.0.22 or newer is now required), open /plugins, select Magic Context and press ctrl+u, or run opencode plugin update. If you still see this on 0.45.0, please reopen with a log.
Activity
magic-alfonso commentedon Oct 1, 2026
Thanks, that's an accurate trace. A child created inside a short-lived background-subagent process has no owner-bound route, so neither runtime retries nor the sweep can ever delete it.
We'd rather not build the password-and-port fallback. The real fix has landed upstream: anomalyco/opencode#49389 is merged on OpenCode's v2 branch. It gives plugins in-process
session.remove, and it letssession.createset a parent, so children are deleted together with their parent.We're building on that now. Each hidden run becomes a child of the session that triggered it, and it's removed in-process when the run finishes, so the creating process doesn't need a registered service. It works the same inside ephemeral subagent processes.
It needs an OpenCode 2 release newer than 2.0.21, which doesn't include it yet. Once that release ships, we'll require it and remove the current workarounds. Until then,
doctor --fixwith OpenCode closed is the cleanup. I'll post here when it ships.mason: update v0.45.0 release notes for changes since d94695f
magic-alfonso commentedon Oct 4, 2026
Fixed in 0.45.0, now on npm. On OpenCode 2.0.22 and newer, Magic Context creates its background sessions under your session and deletes them through OpenCode's own session API, so nothing reads credentials from the environment. Sessions earlier versions left behind are deleted in small batches at startup.
To update, quit every OpenCode and Pi process first: the database migrates on first start, which can take up to a minute on a large database. OpenCode 1 and Pi pick up the new version on restart. On OpenCode 2 (2.0.22 or newer is now required), open
/plugins, select Magic Context and press ctrl+u, or runopencode plugin update. If you still see this on 0.45.0, please reopen with a log.