[PR #3083] fix: Explicitly exit CLI to prevent hanging subprocesses #10529

Closed
opened 2026-02-16 18:15:12 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/3083

State: closed
Merged: Yes


Reproduced using MCP config from: https://github.com/sst/opencode/issues/1717

The easiest way to reproduce (and verify the fix) is to run opencode run hi.

Investigation:

  • The MCP servers from the issue are run via docker run
  • When opencode exits, the ai library sends SIGTERM to all child MCP processes that use stdio transports
  • The problem is that the child processes are the docker run client, and SIGTERM isn't properly delivered, unless docker run --init was used. So the subprocesses stick around, preventing opencode from exiting. I verified this with a minimalistic subprocess-spawning bun program and strace
  • What does work though, is killing the opencode process itself using process.exit, in which case SIGTERM is delivered correctly
  • Fix: I added a process.exit() when the CLI is done with everything.

NOTE: Issue also happens in (some, maybe all) MCP servers wrapped by shell scripts, which this also fixes.


Edit:
I also found some places that don't properly await Promises and are liable to cause hangs before process exit. I changed those. I also replaced some for () { await ... } with await Promise.all(...) to potentially speed up cleanups of unrelated resources (which hence can be performed concurrently).

Improved INFO logs for ensureTitle - it's now awaited and logged so it can be more obvious from --print-logs that that is the reason why OC hangs before exiting.


Closes #854.
Closes #1001.
Closes #1195.
Closes #1431.
Closes #1717.
Closes #1810.

Might fix:

Possibly related, but I'm not very confident this is fixed by the PR:

**Original Pull Request:** https://github.com/anomalyco/opencode/pull/3083 **State:** closed **Merged:** Yes --- Reproduced using MCP config from: https://github.com/sst/opencode/issues/1717 The easiest way to reproduce (and verify the fix) is to run `opencode run hi`. Investigation: - The MCP servers from the issue are run via `docker run` - When opencode exits, the `ai` library sends SIGTERM to all child MCP processes that use stdio transports - The problem is that the child processes are the `docker run` client, and `SIGTERM` isn't properly delivered, unless `docker run --init` was used. So the subprocesses stick around, preventing opencode from exiting. I verified this with a minimalistic subprocess-spawning bun program and `strace` - What does work though, is killing the opencode process itself using `process.exit`, in which case `SIGTERM` is delivered correctly - Fix: I added a `process.exit()` when the CLI is done with everything. NOTE: Issue also happens in (some, maybe all) MCP servers wrapped by shell scripts, which this also fixes. --- Edit: I also found some places that don't properly await Promises and are liable to cause hangs before process exit. I changed those. I also replaced some `for () { await ... }` with `await Promise.all(...)` to potentially speed up cleanups of unrelated resources (which hence can be performed concurrently). Improved INFO logs for ensureTitle - it's now awaited and logged so it can be more obvious from `--print-logs` that that is the reason why OC hangs before exiting. --- Closes #854. Closes #1001. Closes #1195. Closes #1431. Closes #1717. Closes #1810. Might fix: - #2406. - #3213 Possibly related, but I'm not very confident this is fixed by the PR: - #2819
yindo added the pull-request label 2026-02-16 18:15:12 -05:00
yindo closed this issue 2026-02-16 18:15:12 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#10529