#18126: Fix process tree kill leaving orphans on Unix (manual traversal fallback)
size: S
trusted-contributor
Cluster:
Node and macOS Enhancements
## Description
Previously, `killProcessTree` tried `process.kill(-pid)` which only works if the pid is a process group leader. When processes are spawned without `detached: true`, they share the parent's group, so this call fails. Fallback was `process.kill(pid)`, which left children orphaned.
## Fix
Added manual descendant discovery using `pgrep -P` when group kill fails, ensuring the entire tree is terminated.
## AI Transparency
- **Assisted by**: OpenClaw Agent (Claude 3.5 Sonnet / Opus)
- **Testing level**: Fully tested with new unit tests
- **Prompt strategy**: Self-correction loop based on codebase analysis
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR fixes orphaned child processes on Unix by adding `pgrep -P` based manual tree traversal when `process.kill(-pid, "SIGKILL")` fails (i.e., when the target process is not a process group leader). The implementation uses a BFS to discover all descendants before killing them bottom-up, then kills the root process last.
- Adds `getChildrenUnix()` helper using `execSync('pgrep -P <pid>')` for child PID discovery
- Replaces the old SIGTERM → grace period → SIGKILL flow with immediate SIGKILL (consistent with how all callers use this function — they only invoke it when SIGKILL is intended)
- Adds a new Unix-specific integration test verifying tree termination via the manual traversal path
- **Important**: A duplicate `killProcessTree` in `src/agents/shell-utils.ts` (used by `auto-reply/reply/bash-command.ts` and e2e tests) still has the old orphan-producing fallback and was not updated
<h3>Confidence Score: 3/5</h3>
- The core fix is sound but the duplicate implementation in shell-utils.ts means the orphan bug persists for some callers.
- The pgrep-based tree traversal is a correct fix for the orphan problem, and the test validates the new path. Score is 3 rather than higher because the same bug exists in a duplicate killProcessTree in src/agents/shell-utils.ts that was not updated, leaving some call sites still vulnerable to orphaned processes.
- src/agents/shell-utils.ts contains a duplicate killProcessTree that was not updated with the same fix and still orphans children.
<sub>Last reviewed commit: e4f4d21</sub>
<!-- greptile_other_comments_section -->
<sub>(1/5) You can manually trigger the agent by mentioning @greptileai in a comment!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#16157: fix(security): OC-31 scope process cleanup to owned PIDs
by aether-ai-agent · 2026-02-14
78.6%
#17862: fix: Windows exec returns empty output when pty=false
by MisterGuy420 · 2026-02-16
75.6%
#11362: fix: name parent shim processes for clarity in ps output
by anooprdawar · 2026-02-07
75.3%
#6577: fix: add null checks for stdout/stderr when using inherit-stdio fal...
by ncmalan · 2026-02-01
73.2%
#8038: fix(exec): use spawnWithFallback to handle EBADF on macOS
by FelixFoster · 2026-02-03
72.8%
#15852: fix: pass agentId when resolving IRC session paths
by MisterGuy420 · 2026-02-14
72.7%
#19495: fix: handle Chrome process re-parenting on Windows
by andenwick · 2026-02-17
72.6%
#2541: fix(agents): add error handling to orphaned message cleanup
by Episkey-G · 2026-01-27
72.4%
#22721: fix(exec): keep child runs attached on macOS for reliable output
by rylena · 2026-02-21
72.1%
#5014: fix(agents): detect PID reuse in session write lock
by shayan919293 · 2026-01-30
71.1%