Skip to content

fix(ext/node): set up stdio streams on failed child_process spawn#32698

Merged
fraidev merged 1 commit intodenoland:mainfrom
fraidev:fix/child-process-stdio-on-spawn-failure
Mar 14, 2026
Merged

fix(ext/node): set up stdio streams on failed child_process spawn#32698
fraidev merged 1 commit intodenoland:mainfrom
fraidev:fix/child-process-stdio-on-spawn-failure

Conversation

@fraidev
Copy link
Copy Markdown
Contributor

@fraidev fraidev commented Mar 14, 2026

In Node.js, stdio pipes are created before the OS spawn call, so child.stdout/stderr/stdin are valid stream objects even when spawn fails (e.g. ENOENT). Deno's implementation only created these after a successful Deno.Command().spawn(), leaving them as null on failure.

This caused crashes when code accessed child.stdout after a failed spawn, which is valid and expected in Node.js.

Now when spawn fails, we create the stdio streams, emit the error, then destroy the streams in the next tick so the 'close' event fires correctly (matching Node.js behavior of 'close' without 'exit' on spawn failure).

In Node.js, stdio pipes are created before the OS spawn call, so
child.stdout/stderr/stdin are valid stream objects even when spawn
fails (e.g. ENOENT). Deno's implementation only created these after
a successful Deno.Command().spawn(), leaving them as null on failure.

This caused crashes when code accessed child.stdout after a failed
spawn, which is valid and expected in Node.js.

Now when spawn fails, we create the stdio streams, emit the error,
then destroy the streams in the next tick so the 'close' event fires
correctly (matching Node.js behavior of 'close' without 'exit' on
spawn failure).
@fraidev fraidev merged commit 4d45fe5 into denoland:main Mar 14, 2026
112 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants