Node: Check cwd before spawning child process

Created on 23 Feb 2017  路  16Comments  路  Source: nodejs/node

  • Version: v7.6.0
  • Platform: Darwin Pecorino.local 16.4.0 Darwin Kernel Version 16.4.0: Thu Dec 22 22:53:21 PST 2016; root:xnu-3789.41.3~3/RELEASE_X86_64 x86_64

When a cwd is passed to child_process.spawn() that does not exist, node just reports ENOENT:

const spawn = require("child_process").spawn

spawn(process.execPath, { cwd: "/does/not/exist" });
> Error: spawn /usr/local/bin/node ENOENT
    at exports._errnoException (util.js:1028:11)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:193:32)
    at onErrorNT (internal/child_process.js:359:16)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickDomainCallback (internal/process/next_tick.js:122:9)

This error message is very confusing because it reads like /usr/local/bin/node does not exist. It took me several hours to debug this issue, including serious doubts in my sanity 馃榿.

Do you think it is feasible to check the cwd before spawning the process, or is there a use-case/is it possible to spawn a process with a non-existent cwd? If it's not feasible, would it be an option to include the cwd in the error message to give a slight hint in the right direction?

child_process feature request libuv

Most helpful comment

Could you do a check after the fact simply for the purpose of giving a better error message? i.e. if you get an ENOENT, check if the cwd exists, if not then give an error message specific to that. In the worst case you provide a wrong error message, but not a wrong program behavior.

All 16 comments

That's going to be difficult because the error needs to bubble up from a long way down. I don't think it can be done without backwards-incompatible changes to libuv, which means it won't happen before libuv v2.0.

That's going to be difficult because the error needs to bubble up from a long way down

This means that checking the cwd beforehand (with fs.exists for instance) is not an option?

No, that's prone to race conditions (TOCTOU issues.) It's going to work alright 99% of the time and that might be acceptable for an npm module but requirements for node.js core are more stringent.

I have this problem on Sierra but it works as I expect it on Win10.
As soon as I set a _cwd_, I get the EONENT error. I can reproduce it simply in the REPL with
:+1: require('child_process').spawn('ls', [], {stdio:'inherit'})
:-1: require('child_process').spawn('ls', [], {stdio:'inherit', cwd:'~/projects'})
> Error: spawn is ENOENT

I succeed to use a _cwd_ on Win10 with ...spawn('dir'...

How about add an option checkCWD?

something like:

.spawn(path, { cwd: "some/cwd", checkCWD: true });

Check-before-use is an anti-pattern. It's not something to codify in the API.

To make it clear: the path I give in _cwd_ is valid.

@mrpeu Probably because you use ~ in the file path. No shell expansion is done.

Oooh! Thank you very much!
That means my message polluted this conversation, sorry about that

Check-before-use is an anti-pattern.

@bnoordhuis why is that?

@gibfahn Because it's vulnerable to race conditions: there is a time window between the check and the use where the resource can change or disappear. Every TOCTOU bug ever is a variation on that theme.

@mrpeu No problem, hope it's working for you now.

Doesn't the current code follow TOCTOU? (though the window between TOC and TOU is narrow)

Given the error is captured right and only issue is with the error message, how about making this explicit in the doc?

Could you do a check after the fact simply for the purpose of giving a better error message? i.e. if you get an ENOENT, check if the cwd exists, if not then give an error message specific to that. In the worst case you provide a wrong error message, but not a wrong program behavior.

Still happening to me. Is there at least a manual way to work around this? Ubuntu on armv7.

@ctday You can check after the fact whether it is the cwd or the node executable that is ENOENT (use fs.stat()).

Ok, thanks.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

danielstaleiny picture danielstaleiny  路  3Comments

fanjunzhi picture fanjunzhi  路  3Comments

ksushilmaurya picture ksushilmaurya  路  3Comments

stevenvachon picture stevenvachon  路  3Comments

srl295 picture srl295  路  3Comments