nodejs / nodejs/node

Under Windows, spawning a `pwsh` child process using `spawn` and `detached: true` does not work

Open
#51,018 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
122k
Forks
37.3k
Avg merge
4d 2h
Merged PRs (30d)
283

Description

Version

v20.9.0

Platform

Microsoft Windows NT 10.0.22621.0 x64

Subsystem

child_process

What steps will reproduce the bug?

With this Node.js program:

import {spawn} from 'node:child_process';

const timer = `Running program`;
console.time(timer);
process.on('exit', () => console.timeEnd(timer));

const options = {
	detached: true, stdio: 'ignore', // try commenting to see both sub processes work but not being detached
};
const procNode = spawn('node', ['test-detached.js'], options); procNode.unref(); // always works
const procPwsh = spawn('pwsh', ['-File', 'test-detached.ps1'], options); procPwsh.unref(); // fails when detached: true

and those files next to it:

test-detached.js

import {writeFile} from 'node:fs/promises';
import {setTimeout} from 'node:timers/promises';

await setTimeout(2000);
await writeFile('from-node.txt', 'Hello from Node.js');

test-detached.ps1

Start-Sleep -Seconds 2
'Hello from PowerShell (pwsh)' > ./from-pwsh.txt

You can see that when activating the detached option, only from-node.txt is generated (after 2 seconds), and the parent program indeed doesn't wait for the child processes to complete.

If you deactivate that option, you can see both files from-node.txt and from-pwsh.txt appear, but the parent process waits (around 2 seconds + overhead).

How often does it reproduce? Is there a required condition?

It always happens.

What is the expected behavior? Why is that the expected behavior?

The PowerShell execution should go through.

What do you see instead?

The PowerShell execution does not go through.

Additional information

I am a bit clueless here. Given the fact it works with node.exe but doesn't with pwsh.exe, it is clearly contextual.

Either Node.js should handle such cases automatically, or it should open its API more to allow fine tuning the spawn configuration to make such cases work. I am really wondering what PowerShell does/expects to have the process fail.

Note that according to one of the comments on this thread on StackOverflow, it seems to be an issue on Windows only. So maybe indeed a need to adjust the use of Windows APIs...

I may push my investigation further and post updates here. For instance I'll try the same test from Python. I'll also double check on Linux.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the child_process.spawn entry point and reproduce the Windows case with test-detached.js and test-detached.ps1 using detached: true and stdio: 'ignore'. Compare the working node child with the failing pwsh child and trace the Windows detached-process handling. Done means pwsh runs independently and creates from-pwsh.txt while the parent exits without waiting.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js, powershell
Domain
backend, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.