17 Answers
17

The problem of this error is, there is really little information in the error message to tell you where the call site is, i.e. which executable/command is not found, especially when you have a large code base where there are a lot of spawn calls. On the other hand, if we know the exact command that cause the error then we can follow @laconbass' answer to fix the problem.

I found a very easy way to spot which command cause the problem rather than adding event listeners everywhere in your code as suggested in @laconbass' answer. The key idea is to wrap the original spawn call with a wrapper which prints the arguments send to the spawn call.

Here is the wrapper function, put it at the top of the index.js or whatever your server's starting script.

Here's another idea: just change spawn() to exec() and try again. exec() will tell you what command it tried to run.
– Adam MonsenApr 16 '15 at 5:08

1

Important: Make sure to place the code above as close to the start of the main JS file as possible. If you load other modules first, they can stash away the 'spawn' function and the override here will never be called.
– Dan NissenbaumJun 21 '15 at 0:47

1

I have no luck using the script. It doesn't work at all.
– newguyNov 3 '16 at 8:28

1

This worked perfectly for me. I just put this at the top of my gulpfile.js file, and bingo bango bongo, spawn logging!
– Yann DuranMar 3 '17 at 7:12

The absence of PATH (i.e., it's undefined) will cause spawn to emit the ENOENT error, as it will not be possible to locate any command unless it's an absolute path to the executable file.

When PATH is correctly set, proceed to next step. It should be a directory, or a list of directories. Last case is the usual.

Step 4: Ensure command exists on a directory of those defined in PATH

Spawn may emit the ENOENT error if the filename command (i.e, 'some-command') does not exist in at least one of the directories defined on PATH.

Locate the exact place of command. On most linux distributions, this can be done from a terminal with the which command. It will tell you the absolute path to the executable file (like above), or tell if it's not found.

Example usage of which and its output when a command is found

> which some-command
some-command is /usr/bin/some-command

Example usage of which and its output when a command is not found

> which some-command
bash: type: some-command: not found

miss-installed programs are the most common cause for a not found command. Refer to each command documentation if needed and install it.

When command is a simple script file ensure it's accessible from a directory on the PATH. If it's not, either move it to one or make a link to it.

Once you determine PATH is correctly set and command is accessible from it, you should be able to spawn your child process without spawn ENOENT being thrown.

This has been very helpful to my debugging of Spawn ENOENT. I've referenced it multiple times. Thanks!
– CodeManiakJul 9 '15 at 22:13

24

I've also found that ENOENT will be thrown if you specify cwd in the options, but the given directory does not exist.
– Daniel ImfeldNov 19 '15 at 22:37

4

@DanielImfeld TOTAL SAVIOUR. You should write an answer that says this.
– GreenAsJadeNov 29 '15 at 8:37

2

When you are using spawn('some-command', ['--help'], { env: env }); as exemplified by Step 3 in this answer and are passing a custom environment, be sure to specify the PATH, for instance: { env: { PATH: process.env.PATH } }. The env option will not inherit variables from your current env by default.
– antyAug 11 '16 at 11:52

1

I was able to solve my issue by passing shell: true to the spawn options.
– NickofthymeJan 24 at 23:20

this is because then the cp.on('exit', fn) event will always fire, as long as bash is installed, otherwise, the cp.on('error', fn) event might fire first, if we use it the first way, if we launch 'npm' directly.

This is one of the most useful answer I have come across. I was doing it all wrong until I saw this answer. I was more into using the 1st wrong way of doing it. Thanks for this.
– bozzmobNov 13 '17 at 16:06

For anyone who might stumble upon this, if all the other answers do not help and you are on Windows, know that there is currently a big issue with spawn on Windows and the PATHEXT environment variable that can cause certain calls to spawn to not work depending on how the target command is installed.

In my case, I was getting this error thrown due to the necessary dependent system resources not being installed.

More specifically, I have a NodeJS app that is utilizing ImageMagick. Despite having the npm package installed, the core Linux ImageMagick was not installed. I did an apt-get to install ImageMagick and after that all worked great!

I was getting this error when trying to debug a node.js program from within VS Code editor on a Debian Linux system. I noticed the same thing worked OK on Windows. The solutions previously given here weren't much help because I hadn't written any "spawn" commands. The offending code was presumably written by Microsoft and hidden under the hood of the VS Code program.

Next I noticed that node.js is called node on Windows but on Debian (and presumably on Debian-based systems such as Ubuntu) it's called nodejs. So I created an alias - from a root terminal, I ran

ln -s /usr/bin/nodejs /usr/local/bin/node

and this solved the problem. The same or a similar procedure will presumably work in other cases where your node.js is called nodejs but you're running a program which expects it to be called node, or vice-versa.

If you're on Windows Node.js does some funny business when handling quotes that may result in you issuing a command that you know works from the console, but does not when run in Node. For example the following should work:

spawn('ping', ['"8.8.8.8"'], {});

but fails. There's a fantastically undocumented option windowsVerbatimArguments for handling quotes/similar that seems to do the trick, just be sure to add the following to your opts object:

@laconbass This is an obviously trivial example to convey the concept and so the quotes could be removed. However, there are cases where you absolutely need to quote the arguments (for example if you need to pass an argument that has a path with a space in it: "C:\Program Files\..."). I posted it here because, even though it may not have been the cause of your specific error case, it will hopefully help someone else experiencing this cryptic error because of Node's handling of quotes on Windows like I was encountering.
– Joel BJun 30 '17 at 23:51

node.js already makes some Black Magic and silently quotes arguments "properly". Your example should work without the undocumented option you mention, by unquoting argument inside the array.
– laconbassJul 4 '17 at 23:00

Just to add my own experience, I was running a java process from node. This error happened to me because of quotes around the command, rather than the argument. Test with spaces in the command path and it still works without quotes
– TroncosoNov 16 '18 at 12:47

I was also going through this annoying problem while running my test cases, so I tried many ways to get across it. But the way works for me is to run your test runner from the directory which contains your main file which includes your nodejs spawn function something like this: