Skip to content

OpenCode leaves an orphaned process when it itself is killed #11527

@TomasHubelbauer

Description

@TomasHubelbauer

Description

When I run OpenCode programatically using await Bun.spawn(["opencode"]), it spawns a sub-process moments after starting up which then becomes orphaned (it deparents from the opencode process that spawned it and its PPID becomes 1).

When I kill the OpenCode instance I started by PID, it won't kill the sub-process since it has deparented.

Bun will keep running until the orphaned process dies as it was never unref'd from Bun's PoV (only from the PoV of the Open Code process that spawned it).

This is a problem for use-cases where OpenCode is invoked programmatically (Git hooks for qualitative validations, solutions for terminal mirroring not based on SSH but on Bun's Terminal API etc.)

Plugins

none

OpenCode version

1.1.48

Steps to reproduce

Run:

console.log("Killing all OpenCode instance to ensure clean slate…");
await Bun.$`killall -KILL opencode`.nothrow();

console.log("Printing running OpenCode instances…");
console.log("\t(There should be none)");
await Bun.$`pgrep -fl opencode`.nothrow();

console.log("Starting OpenCode…");
const proc = await Bun.spawn(["opencode"]);
console.log("Started OpenCode. PID:", proc.pid);

const timeout = 100;
console.log(`Waiting for ${timeout} ms for the orphan (worker?) to deparent…`);
await Bun.sleep(timeout);

console.log(`Killing OpenCode with PID ${proc.pid}…`);
proc.kill("SIGKILL");
await proc.exited;
console.log(`Killed OpenCode with PID ${proc.pid}. ${proc.signalCode}`);

console.log("Printing running OpenCode instances…");
console.log("\t(There should be none, but there is one with PPID 1 - orphan)");
await Bun.$`pgrep -fl opencode`.nothrow();

console.log("Killing self to prevent blockage due to ref'd deparented process");
process.exit();

You will see that it starts off with no orphans, then it spawns OpenCode, waits for OpenCode to spawn the sub-process (maybe some worker?), but then the sub-process immediately becomes deparented. Next, the OpenCode instance that was started gets killed and we query running opencode processes - there should be one, but the one orphan remains.

This script is re-entrant, on the next run, it will kill the orphan, run again and leave another orphan, demonstrating the problem.

Screenshot and/or share link

No response

Operating System

No response

Terminal

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions