OpenClaw

OpenClaw keeps child-process errors from severing signal forwarding

OpenClaw closed a report that child-process errors could disable signal forwarding before exit and paired it with a process fix. A related ACP change closes unhealthy runtime handles, placing cleanup and signal ownership on the same lifecycle path.

← Back to homeOriginal source ↗

openclaw/openclaw PR #126493 is the inspected primary source: “fix(process): keep signal forwarding through child errors.” The related records below were inspected as supporting context rather than independent confirmation.

The facts

- openclaw/openclaw PR #126493 was created 2026-08-20T00:50:47Z and was closed at inspection; its title is “fix(process): keep signal forwarding through child errors.” - openclaw/openclaw issue #126488 was created 2026-08-20T00:11:23Z and was closed at inspection; its title is “Child process errors can disable signal forwarding before exit.” - openclaw/openclaw PR #126494 was created 2026-08-20T00:51:01Z and was closed at inspection; its title is “fix(acp): close unhealthy runtime handles [AI].” - The repository reported 386805 stars, 5792 open issues, default branch main, and last push 2026-08-20T01:16:30Z. - The latest tagged-release baseline checked was v2026.8.1-beta.2 published 2026-08-15T05:36:23Z.

What changed

openclaw/openclaw PR #126493 reports: Closes #126488 What Problem This Solves Fixes an issue where a failed signal delivery or IPC operation could make a live CLI respawn, relaunched TUI, or fleet logs --follow child stop receiving later parent termination signals. Node reports those operational failures through the child's error event without necessarily ending the process, but OpenClaw treated every child error as terminal and released process ownership early. Why This Change Was Made The shared child-process bridge now keeps signal forwarding installed until Node reports the terminal exit or close lifecycle event. The respawn runner, TUI launcher, and Fleet stream runner keep persistent error listeners and settle immediately only for a true spawn failure, identified by an undefined child PID. Successful exit and spawn-failure behavior remain unchanged, while post-spawn errors no longer cancel respawn escalation or release terminal/stream ownership. This is the canonical owner-boundary repair: Node's error event is an operational report, while exit and close own terminal state. A shared exported helper or broader bridge API was rejected because the three local PID checks express the dependency contract without expanding the process API. Detaching only on close was also rejected because exit preserves prompt signal-listener cleanup for normally terminated children. User Impact Supervisors and operators can continue to stop respawned CLI, TUI, and Fleet follow processes after a transient signal or IPC failure.

openclaw/openclaw issue #126488 reports: Bug type Behavior bug (incorrect output/state without crash) Beta release blocker No Summary Child-process signal forwarding is detached by nonterminal error events, so later parent signals can leave live CLI, TUI, or Fleet children orphaned. Steps to reproduce 1. Attach the shared child-process bridge to a child whose PID is defined. 2. Emit a child error representing a failed signal delivery such as EPERM, while leaving the child live. 3. Send a later parent termination signal. 4. Observe that the bridge removed its parent signal listener and did not call the child's kill() method. Expected behavior Signal forwarding remains installed until the child reaches a terminal exit or close event. A spawn failure with no PID still settles as an error. Actual behavior The first child error removes the bridge listeners. The respawn runner, TUI launcher, and Fleet log follower also treat every child error as terminal even though Node can emit errors for failed kill() or IPC operations while the child remains live. OpenClaw version Current main source at e7416498560f2f7afe0f7cf328fea9d547bf06d3 Operating system macOS 26.6.1 Install method Source checkout Model N/A (process lifecycle) Provider / routing chain N/A (process lifecycle) Additional provider/model setup details N/A Logs Screenshots, recordings, and evidence Node's ChildProcess contract distinguishes nonterminal error events from terminal exit/close events. Failed spawn has no PID and proceeds from error

openclaw/openclaw PR #126494 reports: What Problem This Solves Fixes an issue where an ACP session whose cached runtime became unhealthy could start a replacement without closing the old runtime handle. That could retain an ACPX delegate, its adapter process tree, and the associated process lease after the successor was published. Why This Change Was Made ManagerRuntimeHandleCache.isReusable now remains a pure health predicate. When it reports an unhealthy status or a probe error, the existing replacement owner retains the old cache entry, closes that exact runtime handle, clears it in finally, and only then ensures and publishes the successor. The separate dispose-vs-new-ensure task #51 remains a known follow-up and is intentionally outside this change. User Impact Operators replacing a dead ACP runtime no longer risk leaving its ACPX delegate or subprocess tree behind. Healthy-handle reuse is unchanged, and this adds no configuration, protocol, storage, or public API surface. Evidence Pre-fix reproduction: the dead-session replacement scenario observed zero runtime closes because the health predicate removed the cache entry before replacement cleanup. node scripts/run-vitest.mjs src/acp/control-plane/manager.runtime-handles.test.ts — 14/14 passed; the regression asserts the old handle is closed exactly once before the successor is ensured. node scripts/run-vitest.mjs src/acp/control-plane/manager.test.ts src/acp/control-plane/manager.failover.test.ts — 33/33 passed across manager concurrency and failover behavior. node scripts/run-vitest.mjs extensions/acpx/src/runtime.test.ts -t "marks the session fresh after discardPersistentState close|releases managed OpenClaw tools MCP delegates after close|cleans up OpenClaw-owned ACPX

Why it matters

Shutdown signals are authority, not decoration. If an error removes forwarding before the child exits, supervisors lose the ability to stop or account for the remaining process tree. The operator test is whether the system remains bounded and its receipts still describe the action after failure, retry or restart.

Current

The primary record was closed when captured on 2026-08-20. The tagged-release baseline was v2026.8.1-beta.2 published 2026-08-15T05:36:23Z. Repository metadata, full source bodies, current pull requests and issues, releases, Google News, Hacker News, Lobsters, Metamesh and the rendered ClawCharts row were inspected. ClawCharts selected the subject; it did not prove the claim.

Evidence

The primary URL is https://github.com/openclaw/openclaw/pull/126493. Supporting records are https://github.com/openclaw/openclaw/issues/126488 and https://github.com/openclaw/openclaw/pull/126494. Source bodies, timestamps and states are preserved in the daily evidence bundle. Test counts and reproductions remain attributed to their authors unless identified as independently rerun.

Source boundary

Open work is described as open, closed work as closed, and operator reports as reports. A pull request is evidence of proposed or reviewed direction, not proof of a shipped release. Search residue, package mirrors and historically published source spines were excluded.

Operator take

Keep signal forwarding alive until child ownership ends, close unhealthy runtime handles explicitly, and verify no descendant survives the terminal receipt. Preserve a before-state receipt, make the smallest reversible change, and verify the original failure independently.

Caveat

Public project records are mutable. Status, scope and evidence can change after publication. This brief records the inspected state and does not authorize changes to a reader’s deployment.

Source inspected; source state, environment and release boundary remain explicit.