Summary
Process.stop() in packages/opencode/src/util/process.ts sends only proc.kill() (SIGTERM) with no timeout and no SIGKILL escalation. If an LSP server ignores SIGTERM (e.g. rust-analyzer, clangd, Java-based servers), the process remains as a zombie.
Root Cause
The abort handler in Process.spawn() (same file) already has the correct pattern: SIGTERM → 5s timeout → SIGKILL. But stop() was written as a simple synchronous proc.kill() without any follow-up.
Impact
- Orphaned LSP processes accumulate, consuming memory and file descriptors
- Instance disposal hangs if a server doesn't respond to SIGTERM
- The
process.exit() fallback in index.ts only cleans up on main-process exit, not during normal operation
Steps to Reproduce
- Use an LSP server that ignores SIGTERM (e.g. some configurations of rust-analyzer or clangd)
- Close the project or instance
- The LSP process remains running
Related
Summary
Process.stop()inpackages/opencode/src/util/process.tssends onlyproc.kill()(SIGTERM) with no timeout and no SIGKILL escalation. If an LSP server ignores SIGTERM (e.g. rust-analyzer, clangd, Java-based servers), the process remains as a zombie.Root Cause
The
aborthandler inProcess.spawn()(same file) already has the correct pattern: SIGTERM → 5s timeout → SIGKILL. Butstop()was written as a simple synchronousproc.kill()without any follow-up.Impact
process.exit()fallback inindex.tsonly cleans up on main-process exit, not during normal operationSteps to Reproduce
Related