[Windows Desktop] Opening generated files can trigger uncaught write EPIPE in custom json_stdin handler

Open 💬 0 comments Opened Aug 26, 2026 by MiniAvatar

What version of the Codex App are you using?

  • Codex Desktop Microsoft Store package: 26.820.7780.0
  • Bundled app release observed locally: 26.820.60940
  • Chromium runtime: 151.0.7922.170
  • Node runtime: 24.14.0

What platform is your computer?

Windows 10 22H2, build 19045, x64.

What issue are you seeing?

Codex Desktop repeatedly displays a blocking Electron main-process modal:

A JavaScript error occurred in the main process

Uncaught Exception:
Error: write EPIPE
    at afterWriteDispatched (node:internal/stream_base_commons:159:15)
    at writeGeneric (node:internal/stream_base_commons:150:3)
    at Socket._writeGeneric (node:net:966:11)
    at Socket._write (node:net:978:8)
    at writeOrBuffer (node:internal/streams/writable:570:12)
    at _write (node:internal/streams/writable:499:10)
    at Writable.end (node:internal/streams/writable:821:17)
    at Socket.end (node:net:737:31)
    at .../app.asar/.vite/build/main-TomazcfO.js:291:4276
    at new Promise (<anonymous>)

The modal blocks normal work until dismissed. It occurred twice in one session, approximately 32 minutes apart.

Steps that likely reproduce the bug

  1. Ask Codex to generate files, such as SVG files.
  2. From a task result/file card, use an open/right-click action to open two generated SVG files in an external application such as VS Code.
  3. The external handler exits or closes its standard input quickly.
  4. Codex displays the uncaught write EPIPE main-process modal.

The failure is recurrent but timing-sensitive.

Packaged-build evidence

Inspection of the installed app bundle maps the reported frame at main-TomazcfO.js:291:4276 to a shared external-command launcher. That launcher:

  • creates a child process inside new Promise(...);
  • registers an error handler on child.stdin;
  • immediately calls child.stdin.end(payload) when stdin data is supplied.

The observed caller that supplies stdin in this path is the custom file-handler branch of the open-in-targets service, using input: "json_stdin".

This evidence suggests a race in which an external file handler exits or closes its pipe before the asynchronous stdin.end() write completes. The resulting EPIPE still reaches Electron's main-process uncaught-exception dialog. This is an inference from the packaged build and reproduction timing, not yet a deterministic minimal reproducer.

This appears distinct from the currently reported IPC/Git paths:

  • #35985: browser-sidebar IPC client lifecycle
  • #38360: recurring Windows modal with browser-pipe evidence
  • #39228: macOS IPC client churn, which explicitly notes that the final unhandled writer may be a separate socket path

Searches for EPIPE "open-in-targets" and EPIPE json_stdin in this repository returned no existing issue.

Expected behavior

  • Opening generated files in VS Code or another external application must not display a main-process exception.
  • A child process closing stdin early should be handled as an external-handler lifecycle failure.
  • Expected EPIPE/EOF during handler teardown should not escape to Electron's uncaught-exception dialog.
  • Users should not need to avoid opening generated artifacts from Codex.

Suggested repair direction

Please audit the open-in-targets/custom json_stdin command runner:

  • retain an error listener for the entire writable lifetime;
  • handle both completion and failure around stdin.end(payload);
  • make child exit, stdin error, and close resolution idempotent;
  • treat stdin.destroyed, stdin.writable, and stdin.writableEnded only as useful preconditions, not as a complete race fix;
  • suppress expected EPIPE/EOF during handler teardown from the process-level uncaught-exception path;
  • add a regression test in which the target process exits before or during the stdin write.

View original on GitHub ↗