Skip to content

[BUG] Opencode process survives terminal close — missing SIGHUP handler causes orphaned process accumulation #12767

@blackas

Description

@blackas

Description

When a terminal session (tab/window) is closed, the opencode process and its child LSP servers are not terminated. They remain running as orphaned processes (TTY = ??), accumulating over time and consuming significant memory.

This indicates opencode does not handle the SIGHUP signal, which the OS sends to foreground processes when their controlling terminal is closed.

Environment

  • OS: macOS 26.2 (Apple Silicon, arm64)
  • OpenCode: v1.1.53
  • Terminal: iTerm2 / Terminal.app (reproducible in both)

Steps to Reproduce

  1. Open a terminal tab and run opencode in a project directory
  2. Let it fully initialize (LSP servers spawn: pyright, bash-language-server, etc.)
  3. Close the terminal tab/window (not Ctrl+C, just close the tab or quit the terminal app)
  4. Open a new terminal and run: ps aux | grep opencode

Observed Behavior

The closed session's opencode process and all its child LSP servers remain alive as orphaned processes:

$ ps -o pid,ppid,tty,stat,etime,command | grep opencode | grep -v grep
87902 70932 ??   S    06-18:21:02 opencode          # 6+ days, no TTY
36784 22543 ??   S    02-15:52:45 opencode          # 2+ days, no TTY

Key observations:

  • TTY = ?? — controlling terminal is gone
  • STAT = S — sleeping, not zombie (still holding resources)
  • Parent PIDs point to orphaned zsh shells (re-parented to PID 1)
  • Each main process retains its child LSP servers (pyright, bash-language-server, yaml-language-server)

In my case, 10 main opencode processes + 8 child LSP servers = 18 total processes consuming ~3.2 GB RAM, most of which were from old, disconnected sessions.

Expected Behavior

When the controlling terminal is closed (SIGHUP sent):

  1. opencode should catch SIGHUP and perform graceful shutdown
  2. All child LSP server processes should be terminated
  3. No orphaned processes should remain

Root Cause Analysis

opencode does not appear to register a SIGHUP handler. The standard process lifecycle for an interactive CLI tool should handle:

Signal Expected Action
SIGHUP Graceful shutdown (terminal closed)
SIGTERM Graceful shutdown (kill request)
SIGINT Immediate exit (Ctrl+C)

Without SIGHUP handling, every terminal close event leaks one opencode process + N LSP child processes.

Impact

Workaround

Manually kill orphaned processes:

# Find orphaned opencode processes (no TTY)
ps -o pid,tty,etime,command | grep opencode | grep '??'

# Kill them
kill <pid1> <pid2> ...

Metadata

Metadata

Assignees

Labels

perfIndicates a performance issue or need for optimization

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions