Reputation: 17824
events.js:72
throw er; // Unhandled 'error' event
^
Error: spawn ENOENT
at errnoException (child_process.js:1000:11)
at Process.ChildProcess._handle.onexit (child_process.js:791:34)
Author note: Lots of issues with this error encouraged me to post this question for future references.
Related questions:
Upvotes: 551
Views: 824518
Reputation: 5181
simply adding shell: true
option solved my problem:
following code is buggy on windows:
const { spawn } = require('child_process');
const child = spawn('dir');
workaround:
const { spawn } = require('child_process');
const child = spawn('dir', [], {shell: true});
based on Node.js Documentation (thanks to @Boris comment):
Note that:
if the shell option is enabled, do not pass unsanitized user input to this function. Any input containing shell metacharacters may be used to trigger arbitrary command execution.
Upvotes: 113
Reputation: 2112
I had this appear while building gulp-jekyll
in Powershell
on Windows 11
.
nodejs 10 LTS
, gulp v3.9.1
, ruby 3.1
, bundler 2.4.5
, jekyll 4.2.2
This line of code here is the cause of the ENOENT
issue I had with spawn
and bundle
.
return cp.spawn('bundle', [
'exec',
'jekyll',
'build',
'--source=app', '--destination=build/development', '--config=_config.yml', '--profile'
], { stdio: 'inherit' })
.on('close', done);
Two errors returned, and troubleshooting should start here. 🤓🧐
events.js:174
throw er; // Unhandled 'error' event
^
Error: spawn bundle ENOENT
The cp.spawn
is not handling an error Event, so handling that with a simple console.log()
will expose the real error with debug information:
return cp.spawn('bundle', [
'exec',
'jekyll',
'build',
'--source=app', '--destination=build/development', '--config=_config.yml', '--profile'
], { stdio: 'inherit' })
.on('error', (e) => console.log(e))
.on('close', done);
This now provides a lot more information to debug with.
{ Error: spawn bundle ENOENT
errno: 'ENOENT',
code: 'ENOENT',
syscall: 'spawn bundle',
path: 'bundle',
spawnargs:
[ 'exec',
'jekyll',
'build',
'--source=app',
'--destination=build/development',
'--config=_config.yml',
'--profile' ] }
The next step to debug would be using the nodejs 10 LTS
documentation for child_process.spawn(command[, args][, options])
. As already described above, adding the { shell: true }
to the options of spawn is a working solution. This is what solved my problem as well. 😌
{ stdio: 'inherit', shell: true }
This solution is merely a band-aid and could be refactored to handle all environments, but that is out of scope for how to troubleshoot & debug the spawn ENOENT
error on nodejs
.
Upvotes: 3
Reputation: 65
For me I made following changes in package.json.
"version": "0.0.0",
"scripts": {
"dev": "vite --open", // delete this line
"dev": "vite", // with this one
.....
}
Upvotes: -4
Reputation: 1875
Make sure to have the package installed locally. By changing the spawn
command with exec
i got a more detailed error and found out I didn't install the package. Simply run, to check if the package is present:
brew install imagemagick
Upvotes: -1
Reputation: 17824
child_process.spawn
, Credits to @jiaji-zhou. Simple, quick, January 2015Environment issues
PATH
environment variable.Windows-only bugs/quirks
Wrong spawn('command', ['--argument', 'list'], { cwd, env, ...opts })
usage
opts.cwd
) does not exist · see leeroy-brun's answerString
spawn('command --wrong --argument list')
spawn('ENV_VAR=WRONG command')
Array
specified as String
spawn('cmd', '--argument list')
PATH
env variable spawn('cmd', [], { env: { variable } }
spawn('cmd', [], { env: { ...process.env, variable } }
There are 2 posible origins for
ENOENT
:
- Code you are writing
- Code you depend on
When origin is code you depend on, usual cause is an Environment Issue (or windows quirk)
Upvotes: 25
Reputation: 1618
A case that I found that is not in this list but it's worthy to be added:
On Alpine Linux, Node will error with ENOENT if the executable is not compatible.
Alpine expects binaries with libc
. An executable (e.g. chrome
as part of chromium) that has been compiled with glibc
as a wrapper for system calls, will fail with ENOENT when called by spawn
.
Upvotes: 2
Reputation: 229
Tried all nothing worked , my system has different issue .
The working solution for me is run command : npm config set script-shell "C:\Program Files\git\bin\bash.exe"
Upvotes: 0
Reputation: 1512
Recently I also faced similar issue.
Starting the development server...
events.js:174
throw er; // Unhandled 'error' event
^
Error: spawn null ENOENT
at Process.ChildProcess._handle.onexit (internal/child_process.js:240:19)
at onErrorNT (internal/child_process.js:415:16)
at process._tickCallback (internal/process/next_tick.js:63:19)
Emitted 'error' event at:
at Process.ChildProcess._handle.onexit (internal/child_process.js:246:12)
at onErrorNT (internal/child_process.js:415:16)
at process._tickCallback (internal/process/next_tick.js:63:19)
error Command failed with exit code 1.
It was due to having a wrong configuration in .env
file for BROWSER
. I had BROWSER=null
, but it has to be BROWSER=none
. Changing that configuration resolved my issue.
Upvotes: 0
Reputation: 2709
In my case removing node, delete all AppData/Roaming/npm and AppData/Roaming/npm-cache and installing node once again solve the issue.
Upvotes: 0
Reputation: 79
Although it may be an environment path or another issue for some people, I had just installed the Latex Workshop extension for Visual Studio Code on Windows 10 and saw this error when attempting to build/preview the PDF. Running VS Code as Administrator solved the problem for me.
Upvotes: 0
Reputation: 2699
Before anyone spends to much time debugging this problem, most of the time it can be resolved by deleting node_modules
and reinstalling the packages.
If a lockfile exists you might use
yarn install --frozen-lockfile
or
npm ci
respectivly. if not then
yarn install
or
npm i
Upvotes: 11
Reputation: 8778
In case you're experiencing this issue with an application whose source you cannot modify consider invoking it with the environment variable NODE_DEBUG
set to child_process
, e.g. NODE_DEBUG=child_process yarn test
. This will provide you with information which command lines have been invoked in which directory and usually the last detail is the reason for the failure.
Upvotes: 6
Reputation: 19282
env
option?Then look at this answer.
I was trying to spawn a node process and TIL that you should spread the existing environment variables when you spawn else you'll loose the PATH
environment variable and possibly other important ones.
This was the fix for me:
const nodeProcess = spawn('node', ['--help'], {
env: {
// by default, spawn uses `process.env` for the value of `env`
// you can _add_ to this behavior, by spreading `process.env`
...process.env,
OTHER_ENV_VARIABLE: 'test',
}
});
Upvotes: 6
Reputation: 3117
NOTE: This error is almost always caused because the command does not exist, because the working directory does not exist, or from a windows-only bug.
I found a particular easy way to get the idea of the root cause of:
Error: spawn ENOENT
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.
(function() {
var childProcess = require("child_process");
var oldSpawn = childProcess.spawn;
function mySpawn() {
console.log('spawn called');
console.log(arguments);
var result = oldSpawn.apply(this, arguments);
return result;
}
childProcess.spawn = mySpawn;
})();
Then the next time you run your application, before the uncaught exception's message you will see something like that:
spawn called
{ '0': 'hg',
'1': [],
'2':
{ cwd: '/* omitted */',
env: { IP: '0.0.0.0' },
args: [] } }
In this way you can easily know which command actually is executed and then you can find out why nodejs cannot find the executable to fix the problem.
Upvotes: 310
Reputation: 68
I ran into this problem on Windows, where calling exec
and spawn
with the exact same command (omitting arguments) worked fine for exec
(so I knew my command was on $PATH
), but spawn
would give ENOENT. Turned out that I just needed to append .exe
to the command I was using:
import { exec, spawn } from 'child_process';
// This works fine
exec('p4 changes -s submitted');
// This gives the ENOENT error
spawn('p4');
// But this resolves it
spawn('p4.exe');
// Even works with the arguments now
spawn('p4.exe', ['changes', '-s', 'submitted']);
Upvotes: 1
Reputation: 10252
solution in my case
var spawn = require('child_process').spawn;
const isWindows = /^win/.test(process.platform);
spawn(isWindows ? 'twitter-proxy.cmd' : 'twitter-proxy');
spawn(isWindows ? 'http-server.cmd' : 'http-server');
Upvotes: 1
Reputation: 100290
@laconbass's answer helped me and is probably most correct.
I came here because I was using spawn incorrectly. As a simple example:
this is incorrect:
const s = cp.spawn('npm install -D suman', [], {
cwd: root
});
this is incorrect:
const s = cp.spawn('npm', ['install -D suman'], {
cwd: root
});
this is correct:
const s = cp.spawn('npm', ['install','-D','suman'], {
cwd: root
});
however, I recommend doing it this way:
const s = cp.spawn('bash');
s.stdin.end(`cd "${root}" && npm install -D suman`);
s.once('exit', code => {
// exit
});
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.
Upvotes: 32
Reputation: 363
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:
nodeProcess = spawn('node',params, {cwd: '../../node/', detached: true });
For example, this file name is test.js, so just move to the folder which contains it. In my case, it is test folder like this:
cd root/test/
then from run your test runner in my case its mocha so it will be like this:
mocha test.js
I have wasted my more than one day to figure it out. Enjoy!!
Upvotes: 1
Reputation: 17824
spawn
is called the right wayFirst, review the docs for child_process.spawn( command, args, options ):
Launches a new process with the given
command
, with command line arguments inargs
. If omitted,args
defaults to an empty Array.The third argument is used to specify additional options, which defaults to:
{ cwd: undefined, env: process.env }
Use
env
to specify environment variables that will be visible to the new process, the default isprocess.env
.
Ensure you are not putting any command line arguments in command
and the whole spawn
call is valid. Proceed to next step.
Search on your source code for each call to spawn
, or child_process.spawn
, i.e.
spawn('some-command', [ '--help' ]);
and attach there an event listener for the 'error' event, so you get noticed the exact Event Emitter that is throwing it as 'Unhandled'. After debugging, that handler can be removed.
spawn('some-command', [ '--help' ])
.on('error', function( err ){ throw err })
;
Execute and you should get the file path and line number where your 'error' listener was registered. Something like:
/file/that/registers/the/error/listener.js:29
throw err;
^
Error: spawn ENOENT
at errnoException (child_process.js:1000:11)
at Process.ChildProcess._handle.onexit (child_process.js:791:34)
If the first two lines are still
events.js:72
throw er; // Unhandled 'error' event
do this step again until they are not. You must identify the listener that emits the error before going on next step.
$PATH
is setThere are two possible scenarios:
spawn
behaviour, so child process environment will be the same as process.env
.env
object to spawn
on the options
argument.In both scenarios, you must inspect the PATH
key on the environment object that the spawned child process will use.
Example for scenario 1
// inspect the PATH key on process.env
console.log( process.env.PATH );
spawn('some-command', ['--help']);
Example for scenario 2
var env = getEnvKeyValuePairsSomeHow();
// inspect the PATH key on the env object
console.log( env.PATH );
spawn('some-command', ['--help'], { env: env });
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.
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.
Upvotes: 160
Reputation: 13140
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:
const opts = {
windowsVerbatimArguments: true
};
and your command should be back in business.
spawn('ping', ['"8.8.8.8"'], { windowsVerbatimArguments: true });
Upvotes: 0
Reputation: 1703
Use require('child_process').exec
instead of spawn for a more specific error message!
for example:
var exec = require('child_process').exec;
var commandStr = 'java -jar something.jar';
exec(commandStr, function(error, stdout, stderr) {
if(error || stderr) console.log(error || stderr);
else console.log(stdout);
});
Upvotes: 2
Reputation: 465
Ensure module to be executed is installed or full path to command if it's not a node module
Upvotes: 1
Reputation: 731
For ENOENT on Windows, https://github.com/nodejs/node-v0.x-archive/issues/2318#issuecomment-249355505 fix it.
e.g. replace spawn('npm', ['-v'], {stdio: 'inherit'}) with:
for all node.js version:
spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['-v'], {stdio: 'inherit'})
for node.js 5.x and later:
spawn('npm', ['-v'], {stdio: 'inherit', shell: true})
Upvotes: 31
Reputation: 21
Add C:\Windows\System32\
to the path
environment variable.
Go to my computer and properties
Click on Advanced settings
Then on Environment variables
Select Path
and then click on edit
Paste the following if not already present: C:\Windows\System32\
Close the command prompt
Run the command that you wanted to run
Upvotes: -3
Reputation: 45
I ran into the same problem, but I found a simple way to fix it.
It appears to be spawn()
errors if the program has been added to the PATH by the user (e.g. normal system commands work).
To fix this, you can use the which module (npm install --save which
):
// Require which and child_process
const which = require('which');
const spawn = require('child_process').spawn;
// Find npm in PATH
const npm = which.sync('npm');
// Execute
const noErrorSpawn = spawn(npm, ['install']);
Upvotes: 2
Reputation: 4548
As @DanielImfeld pointed it, ENOENT will be thrown if you specify "cwd" in the options, but the given directory does not exist.
Upvotes: 46
Reputation: 667
I got the same error for windows 8.The issue is because of an environment variable of your system path is missing . Add "C:\Windows\System32\" value to your system PATH variable.
Upvotes: -1
Reputation: 151
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.
Upvotes: 0
Reputation: 18593
Windows solution: Replace spawn
with node-cross-spawn. For instance like this at the beginning of your app.js:
(function() {
var childProcess = require("child_process");
childProcess.spawn = require('cross-spawn');
})();
Upvotes: 33
Reputation: 47776
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.
Upvotes: 22