Skip to content

fix(codex): attach stdin error listener to prevent gateway EPIPE crash#67945

Closed
hclsys wants to merge 1 commit into
openclaw:mainfrom
hclsys:fix/codex-app-server-stdin-epipe-67886
Closed

fix(codex): attach stdin error listener to prevent gateway EPIPE crash#67945
hclsys wants to merge 1 commit into
openclaw:mainfrom
hclsys:fix/codex-app-server-stdin-epipe-67886

Conversation

@hclsys
Copy link
Copy Markdown

@hclsys hclsys commented Apr 17, 2026

Summary

Fixes #67886 — attaches a stdin error listener to CodexAppServerClient so the codex app-server subprocess can fail cleanly without taking down the whole OpenClaw gateway daemon.

Root cause

CodexAppServerTransport.stdin is a Node Writable stream. When the subprocess exits after emitting unparseable stdout (for example an interactive prompt on init, or a deprecated-config error), OpenClaw still tries to write the JSON-RPC initialize payload to the now-closed pipe. Node emits an asynchronous error event on that stream; with no listener attached, the default handler rethrows, crashing the entire gateway daemon.

The existing constructor already wires stdout / stderr / error / exit handlers on the child, but never wires anything on stdin. This PR adds a debug-level listener so the pipe teardown noise is absorbed while the existing exit handler continues to run closeWithError.

Changes

  • extensions/codex/src/app-server/client.ts — attach child.stdin.on('error', …) in the constructor, logging at debug level.
  • extensions/codex/src/app-server/transport.ts — widen the typed stdin shape to expose an optional on('error', …) method so tests and alternate transports participate without casting.
  • extensions/codex/src/app-server/client.test.ts — assert that emitting EPIPE on the harness stdin does not throw.

Test plan

  • NODE_OPTIONS=--max-old-space-size=8192 npx tsc --noEmit — no new TS errors on touched files (baseline 243 on main, 243 on branch).
  • pnpm exec oxlint <touched files> — 0 warnings, 0 errors.
  • Added unit test swallows EPIPE errors emitted on stdin after subprocess exit.

Local full vitest run is blocked by pre-existing infra drift on my machine (test/non-isolated-runner.ts fails to resolve base TestRunner import) — reproduces identically on main, so it is not caused by this change. CI should exercise the new test normally.

Wire a no-op 'error' listener on the codex app-server subprocess stdin.
When the child exits after writing unparseable text (init failures,
deprecated config errors) and OpenClaw subsequently writes to the
already-closed pipe, Node emits an asynchronous 'error' event. Without
a listener the default behavior is to throw, which was crashing the
entire gateway daemon instead of letting the existing exit/error
handlers clean up gracefully.

Also widen the transport `stdin` type to expose an optional `on` method
so tests and alternate transports can participate without casting.

Fixes openclaw#67886
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 17, 2026

Greptile Summary

Attaches an error listener to child.stdin in CodexAppServerClient's constructor so EPIPE events emitted on the stdin pipe (e.g., when the Codex subprocess exits before the initialize write completes) are absorbed at debug level instead of crashing the gateway daemon via Node's default unhandled-error-event throw. The CodexAppServerTransport stdin type is widened to optionally expose on('error', …), and a unit test validates the swallowing behavior.

Confidence Score: 5/5

Safe to merge — minimal, targeted fix with correct logic and a direct regression test.

The change is small and focused: one 3-line listener attachment, one optional type widening, and one directly validating test. The error handler does not alter the existing exit / closeWithError flow; EPIPE is purely absorbed at debug level, which is the right behavior for pipe-teardown noise. No P0/P1 findings were identified.

No files require special attention.

Reviews (1): Last reviewed commit: "fix(codex): attach stdin error listener ..." | Re-trigger Greptile

@hclsys

This comment was marked as low quality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Gateway crashes with unhandled write EPIPE when CodexAppServerClient receives unparseable stdout

1 participant