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

Open
opened 2026-02-16 18:09:21 -05:00 by yindo · 3 comments
Owner

Originally created by @TomasHubelbauer on GitHub (Jan 31, 2026).

Originally assigned to: @rekram1-node on GitHub.

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

Originally created by @TomasHubelbauer on GitHub (Jan 31, 2026). Originally assigned to: @rekram1-node on GitHub. ### 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: ```typescript 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_
yindo added the bug label 2026-02-16 18:09:21 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Jan 31, 2026):

This issue might be a duplicate of or related to existing issues. Please check:

  • #10563: Memory Leak: Orphaned processes when terminal closes without explicit exit (38+ orphaned processes found, MCP child processes becoming orphaned with PPID=1)
  • #5525: git bash.exe processes on Windows get orphaned (similar orphaning mechanism)
  • #11225: opencode attach processes not terminated when tmux pane is killed (zombie process accumulation, signal handling issues)
  • #6633: MCP processes not terminated after session ends (no cleanup mechanism)
  • #7261: MCP orphan processes leak when OpenCode crashes
  • #3057: Child processes continue running in background when OpenCode is interrupted (lack of signal propagation)
  • #8203: opencode run hangs forever on API errors (process never exits, automation breaks)

These issues collectively point to a systemic problem with process lifecycle management in OpenCode - subprocesses aren't being properly tracked or cleaned up when parent processes are killed.

Feel free to ignore if your specific case is different from these issues.

@github-actions[bot] commented on GitHub (Jan 31, 2026): This issue might be a duplicate of or related to existing issues. Please check: - #10563: Memory Leak: Orphaned processes when terminal closes without explicit exit (38+ orphaned processes found, MCP child processes becoming orphaned with PPID=1) - #5525: git bash.exe processes on Windows get orphaned (similar orphaning mechanism) - #11225: opencode attach processes not terminated when tmux pane is killed (zombie process accumulation, signal handling issues) - #6633: MCP processes not terminated after session ends (no cleanup mechanism) - #7261: MCP orphan processes leak when OpenCode crashes - #3057: Child processes continue running in background when OpenCode is interrupted (lack of signal propagation) - #8203: opencode run hangs forever on API errors (process never exits, automation breaks) These issues collectively point to a systemic problem with process lifecycle management in OpenCode - subprocesses aren't being properly tracked or cleaned up when parent processes are killed. Feel free to ignore if your specific case is different from these issues.
Author
Owner

@TomasHubelbauer commented on GitHub (Jan 31, 2026):

FYI I am using no MCP servers, the orphaned process is /Users/tom/.bun/install/global/node_modules/opencode-darwin-arm64/bin/opencode.

@TomasHubelbauer commented on GitHub (Jan 31, 2026): FYI I am using no MCP servers, the orphaned process is `/Users/tom/.bun/install/global/node_modules/opencode-darwin-arm64/bin/opencode`.
Author
Owner

@mohamedbouddi7777-dev commented on GitHub (Feb 1, 2026):

Free the world

@mohamedbouddi7777-dev commented on GitHub (Feb 1, 2026): Free the world
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#8177