fix(process): prevent Windows process-tree leaks after taskkill refusal#112202
Open
MohammedAlkindi wants to merge 1 commit into
Open
fix(process): prevent Windows process-tree leaks after taskkill refusal#112202MohammedAlkindi wants to merge 1 commit into
MohammedAlkindi wants to merge 1 commit into
Conversation
Contributor
|
ClawSweeper status: review started. I am starting a fresh review of this pull request: fix(process): prevent Windows process-tree leaks after taskkill refusal This is item 1/1 in the current shard. Shard 0/1. This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking. Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #110789
What Problem This Solves
On Windows, OpenClaw could leak whole child process trees — npx-spawned MCP servers, sub-agents, and bash-tool subprocesses — after a session cancellation or shutdown. When the graceful
taskkill /T(without/F) could not end a console process, cleanup relied solely on a delayed, unref'd force-kill timer; if the owning gateway process exited or restarted inside the grace window, that timer was canceled and the tree was never force-killed.Why This Change Was Made
The Windows path remains graceful-first and retains the grace-period timer as a fallback, while escalating immediately when the graceful taskkill reports failure. It now wires the graceful exit code back to the caller:
taskkill /F /Tfires immediately only when the graceful attempt reports failure and the target PID is still alive, so the leak is closed without waiting out the full window.taskkillreturns the same non-zero exit for "needs /F" and "process not found," so a reported failure isn't proof the tree still exists. Both escalation paths skip the force-kill when the PID is no longer alive, and the decision is latched before that check. The liveness check prevents forced escalation when the PID is already dead at escalation time, reducing the risk of targeting a recycled PID.closeaftererrorwith a negative errno; the runner reports only the first outcome, so a spawn failure is never misread as a non-zero verdict that escalates.The Unix path and the explicit
force: true/signalProcessTree(SIGKILL)paths are unchanged.User Impact
Windows operators no longer accumulate orphaned MCP-server / sub-agent / shell process trees after cancellations and gateway restarts. Cleanup is more prompt (escalates as soon as the graceful attempt is refused) and safer (avoids forced escalation when the original PID is already gone).
Evidence
Windows 11, Node 24.18:
src/process/kill-tree.test.ts: 26/26.src/process/exec.windows.test.ts: 22/22;src/agents/mcp-stdio-transport.test.ts: 9/9.tsgocore + test-src), lint (oxlint), format (oxfmt --check): clean./F(and does receive one when the guard is removed).trufflehog filesystemover both changed files: 0 secrets.AI-assisted (Claude). An initial autoreview surfaced two findings — a missing liveness guard before escalation and escalation on a spawn-error
close— were verified and fixed. The final automated rerun was blocked by a Windows-specific TruffleHog tooling issue, so secret scanning was completed separately (above).