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
- Open a terminal tab and run
opencode in a project directory
- Let it fully initialize (LSP servers spawn: pyright, bash-language-server, etc.)
- Close the terminal tab/window (not
Ctrl+C, just close the tab or quit the terminal app)
- 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):
opencode should catch SIGHUP and perform graceful shutdown
- All child LSP server processes should be terminated
- 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> ...
Description
When a terminal session (tab/window) is closed, the
opencodeprocess and its child LSP servers are not terminated. They remain running as orphaned processes (TTY = ??), accumulating over time and consuming significant memory.This indicates
opencodedoes not handle theSIGHUPsignal, which the OS sends to foreground processes when their controlling terminal is closed.Environment
Steps to Reproduce
opencodein a project directoryCtrl+C, just close the tab or quit the terminal app)ps aux | grep opencodeObserved Behavior
The closed session's
opencodeprocess and all its child LSP servers remain alive as orphaned processes:Key observations:
TTY = ??— controlling terminal is goneSTAT = S— sleeping, not zombie (still holding resources)zshshells (re-parented to PID 1)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):
opencodeshould catchSIGHUPand perform graceful shutdownRoot Cause Analysis
opencodedoes not appear to register aSIGHUPhandler. The standard process lifecycle for an interactive CLI tool should handle:SIGHUPSIGTERMSIGINTWithout
SIGHUPhandling, every terminal close event leaks oneopencodeprocess + N LSP child processes.Impact
Workaround
Manually kill orphaned processes: