-
Notifications
You must be signed in to change notification settings - Fork 9.9k
Description
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
opencodein 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 goneSTAT = S— sleeping, not zombie (still holding resources)- Parent PIDs point to orphaned
zshshells (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):
opencodeshould catchSIGHUPand 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
- Memory leak: ~150-800 MB per orphaned session, accumulating indefinitely
- Process table pollution: 2-5 processes per orphaned session
- Potentially related to: [BUG/PERF] Severe Memory Leak and Disk Swell leading to System Kernel Panic (macOS) #12687 (memory leak leading to kernel panic) — orphaned process accumulation could be a contributing factor
- Similar pattern to: ElixirLS: LSP client spawns new process per request, causing timeout and process leak #12596 (LSP process leak) — both involve child processes not being cleaned up
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> ...