Skip to content

Conversation

@jogi47
Copy link
Contributor

@jogi47 jogi47 commented Feb 1, 2026

Summary

Fixes #11527

When OpenCode is spawned programmatically and then killed, the worker process was left orphaned (PPID becomes 1), blocking the parent process from exiting.

Changes

  • thread.ts: Add SIGTERM/SIGINT handlers to properly shutdown worker before exit
  • worker.ts: Add parent death detection using process.ppid polling (1-second interval)
  • worker.ts: Add SIGTERM/SIGINT handlers for direct signal handling

How it works

  1. Signal handlers in main thread: When SIGTERM or SIGINT is received, the main thread now calls the worker's shutdown RPC before exiting
  2. Parent death detection: Worker polls every 1 second to check if parent is still alive using process.kill(parentPid, 0). If parent dies (even via SIGKILL), worker detects and shuts down
  3. Worker signal handlers: Direct signals to worker are also handled properly

Test plan

  • All 842 existing tests pass
  • Manual verification with reproduction script from issue

🤖 Generated with Claude Code

When OpenCode is spawned programmatically and then killed, the worker
process was left orphaned (PPID becomes 1), blocking the parent process
from exiting.

Changes:
- Add SIGTERM/SIGINT handlers in thread.ts to properly shutdown worker
- Add parent death detection in worker.ts using process.ppid polling
- Add SIGTERM/SIGINT handlers in worker.ts for direct signal handling

The worker now detects if its parent dies (even via SIGKILL) and shuts
itself down within 1 second.

Fixes anomalyco#11527

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions
Copy link
Contributor

github-actions bot commented Feb 1, 2026

The following comment was made by an LLM, it may be inaccurate:

No duplicate PRs found

@jhult
Copy link

jhult commented Feb 6, 2026

I believe this may also resolve #10563.

@shjeong92
Copy link

Nice work on the ppid polling approach — that's a solid safety net for SIGKILL scenarios.

One gap I noticed: this PR handles SIGTERM and SIGINT but not SIGHUP, which is the actual signal sent when a terminal tab/window is closed. That's the core trigger for #10563 (orphaned processes on terminal close).

The fix for #10563 specifically needs process.on("SIGHUP", ...) in both thread.ts and worker.ts. SIGTERM/SIGINT cover kill <pid> and Ctrl+C, but terminal closure sends SIGHUP.

Additionally, attach.ts (#11225) and serve.ts (headless server mode) have the same problem — no signal handling at all, so they also become orphans on terminal close.

I'm working on a broader fix that covers SIGHUP across all long-running entry points (tui, attach, serve) plus a safety net in index.ts. Happy to coordinate if useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenCode leaves an orphaned process when it itself is killed

3 participants