fix(opencode): Memory Leak - Stop OpenCode refresh from leaking serve processes#2359
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 6cd4849. Configure here.
ApprovabilityVerdict: Approved Straightforward bug fix adding proper child process cleanup finalizers to prevent serve process leaks during OpenCode refresh. Changes are self-contained with test coverage and use standard process termination patterns. You can customize Macroscope's approvability policy. Learn more. |
OpenCode can leave the long-lived serve child in the spawned process group after the wrapper exits. Provider refresh owns only a scoped inventory probe, so cleanup targets that local process group when the refresh scope closes. Constraint: Keep active OpenCode thread sessions scoped to their own session lifecycle. Rejected: Disable provider refresh | would hide model and auth state changes. Confidence: high Scope-risk: narrow Tested: bun run test src/provider/Layers/OpenCodeProvider.test.ts src/provider/Layers/OpenCodeAdapter.test.ts Tested: bun fmt Tested: bun lint Tested: bun typecheck Tested: bun run build:desktop
6cd4849 to
71199bb
Compare
|
@juliusmarminge unsure why the smoke failed, CI issue? |
idk if it's related to the ongoing github outages or not... CI passes, just the voucher that doesn't work, don't worry bout it |
|
@juliusmarminge Okay cool. If you need any help replicating the issue I'm happy to demonstrate. Great work on the project so far. Thanks |

What Changed
Fixes cleanup for scoped local OpenCode server processes used during provider refresh/model checks.
The refresh scope now terminates the spawned OpenCode process group when the scoped server is closed, preventing orphaned
opencode serveprocesses from accumulating in the background.Why
OpenCode refresh/model checks could start a temporary local server, but the wrapper process could exit while leaving the actual long-lived serve child alive. Since refresh runs periodically, this could create a new background OpenCode process every cycle and cause memory usage to balloon.
This keeps provider refresh behavior intact and only tightens cleanup for the local refresh-owned OpenCode process. Active OpenCode thread sessions keep their existing lifecycle.
Warning
I couldn't test on windows and the exit logic is slightly different as
process.kill(-pid, signal) is POSIX only. It's correct in theory but should be double checked.Checklist
Constraint: Keep active OpenCode thread sessions scoped to their own session lifecycle.
Confidence: high
Scope-risk: narrow
Tested:
bun run test src/provider/Layers/OpenCodeProvider.test.ts src/provider/Layers/OpenCodeAdapter.test.tsTested:
bun fmtTested:
bun lintTested:
bun typecheckTested:
bun run build:desktopScreenshots
Note
Medium Risk
Changes process-spawning/termination behavior for the local
opencode serveused during provider refresh, including POSIX process-group killing and Windows-specific fallback; mistakes could leave servers running or kill the wrong process. Scope is narrow and covered by a new refresh cleanup test.Overview
Fixes a refresh-time memory leak by ensuring locally spawned
opencode serveprocesses are reliably cleaned up when the refresh scope closes.startOpenCodeServerProcessnow spawns the server detached on non-Windows and registers a scope finalizer that SIGTERM/SIGKILLs the entire process group (or useschild.killon Windows), preventing orphaned background servers from accumulating.Tests update the
OpenCodeRuntimetest double to track scope finalization and add an assertion thatprovider.refreshcloses the local server scope.Reviewed by Cursor Bugbot for commit f446782. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Fix memory leak by terminating OpenCode server processes on scope finalization
detached: trueon non-Windows so the child and its subprocesses form a separate process group.child.kill(Windows), ensuring server processes are cleaned up whenprovider.refreshcompletes.closeCallscounter to the test double and a new test asserting the local server scope is closed after refresh.Macroscope summarized f446782.