fix(imessage): attach stdin error listener to prevent EPIPE gateway crash (#75438)#75608
fix(imessage): attach stdin error listener to prevent EPIPE gateway crash (#75438)#75608hclsys wants to merge 1 commit intoopenclaw:mainfrom
Conversation
…rash (openclaw#75438) stdin write errors (e.g. EPIPE when imsg rpc process closes its stdin) are emitted on the stdin stream, not the child process. Without an error listener they escape to uncaughtException and kill the gateway with exit code 1. Add child.stdin.on("error", ...) in IMessageRpcClient.start() right next to the existing child error listener, routing stdin errors through failAll() so pending requests receive a rejection instead of crashing the process.
|
Thanks for the context here. I did a careful shell check against current Close as implemented on current main. The iMessage RPC stdin EPIPE path that this PR targets is already handled in So I’m closing this as already implemented rather than keeping a duplicate issue open. Review detailsBest possible solution: Close this PR and keep the current main implementation, which handles the iMessage stdin EPIPE failure locally in the plugin with both stream-level and per-write error handling. Any remaining work should be normal release validation for the already-landed main change, not another PR for the same behavior. Do we have a high-confidence way to reproduce the issue? Yes. The reported failure path is source-visible: iMessage uses Is this the best way to solve the issue? Yes for current main. The landed implementation is the narrow maintainable fix because it stays inside the iMessage RPC client and rejects pending requests rather than adding a global uncaught-EPIPE suppression. Security review: Security review cleared: The PR diff only touches iMessage runtime error handling, a unit test, and CHANGELOG.md, with no dependency, workflow, permission, download, publish, or secret-handling changes. What I checked:
Likely related people:
Codex review notes: model gpt-5.5, reasoning high; reviewed against e0cc374b07c1; fix evidence: commit e0cc374b07c1, main fix timestamp 2026-05-01T22:38:47+01:00. |
Summary
IMessageRpcClient.request()callsthis.child.stdin.write(line)with no error callback. When the iMessage RPC child closes its stdin (crash, rate limit, network hiccup), Node emits an asyncerroron the stdin stream with codeEPIPE. The existingchild.on("error", ...)at line 106 does NOT catch stdin stream errors — those fire on the stream, not the child process — so the error escapes touncaughtExceptionand crashes the gateway.Fix: add
child.stdin.on("error", ...)listener immediately after the existingchild.on("error", ...)block, routing errors through the existingfailAll()helper which rejects all pending requests cleanly.Fixes #75438.
Pre-audit
failAllalready exists at line 239. Reused exactly — no new helper introduced.failAllisprivate, only called withinclient.ts. Contract unchanged.Test plan
pnpm test extensions/imessage/src/client.test.ts— 1/1 pass (new test simulates EPIPE via mockedspawn, verifies pending request rejects instead of uncaughtException)git diff --check— clean