Node.js で child_process.spawn や execFile を使って外部コマンドを実行するとき、環境によって頻繁に遭遇するのが「Error: spawn ENOENT」です。
特に Mac・Windows・Docker など環境が異なる場合や、パス設定・実行権限に問題がある場合に発生しやすいエラーです。
この記事では、その原因と代表的な解決策をわかりやすく整理します。
エラーの意味
ENOENT は “Error NO ENTry” の略で、「指定されたファイルやコマンドが見つからない」という意味です。
Node.js の spawn 関数が呼ばれる際、内部で OS にコマンドを実行させようとしますが、そのコマンドのパスが解決できなかった場合にこのエラーが発生します。
Error: spawn someCommand ENOENT
つまり、Node.js 自体が壊れているのではなく、「呼び出そうとしたプログラムが存在しない、または実行できない」ことを示しています。
よくある原因
1. 実行ファイルのパスが通っていない
もっとも一般的な原因です。spawn はシェルを経由せずに直接プロセスを立ち上げるため、コマンドが PATH 環境変数で解決できないと失敗します。
const { spawn } = require('child_process')
spawn('python', ['script.py']) // ← python が PATH にないと ENOENT
例えば、Node.js 実行時の環境に Python がインストールされていない、または PATH が設定されていない場合にこのエラーが出ます。
対策:
- 絶対パスを指定する
spawn('/usr/local/bin/python3', ['script.py']) - もしくは
envオプションで PATH を明示的に渡すspawn('python3', ['script.py'], { env: { ...process.env, PATH: '/usr/local/bin:' + process.env.PATH } })
2. Windows 特有の拡張子解決の違い
Windows では、実行ファイルに .exe, .bat, .cmd などの拡張子が必要ですが、spawn はそれを自動的に解決しません。
次のように書くと ENOENT が出やすくなります。
spawn('npm', ['run', 'build']) // ❌ ENOENT: npm.cmd が実体
対策:
shell: trueを指定してシェル経由で実行するspawn('npm', ['run', 'build'], { shell: true })- または、Windows 専用で拡張子を含める
spawn('npm.cmd', ['run', 'build'])
3. 実行権限がない
Mac や Linux では、対象ファイルに実行権限 (chmod +x) がないと ENOENT が出る場合があります。
chmod +x script.sh
また、リポジトリをクローンしたあとに権限が落ちていることもあるため、CI/CD や Docker 内で再現するケースもあります。
4. Docker や CI 環境での PATH 問題
Docker や CI/CD 環境では、PATH がローカルと異なるため、/usr/local/bin や /usr/bin の中にあるコマンドが見つからない場合があります。
特に node:alpine ベースのコンテナでは、軽量化のために多くの実行ツールが含まれていません。
対策:
- 実際のコンテナ内で PATH を確認する
echo $PATH which node which bash - 必要なツールをインストールする
RUN apk add --no-cache bash python3 - Node.js 側で絶対パスを指定する、または
shell: trueを使う
5. ファイル・スクリプト名のミス
単純なファイル名の打ち間違いや、拡張子の違い(例: .sh と .bash)も原因のひとつです。
また、相対パスを指定した場合に、実行ディレクトリ (process.cwd()) が期待と違うこともよくあります。
spawn('./scripts/deploy.sh') // ❌ 実行ディレクトリが別なら見つからない
対策:
import path from 'path'
spawn(path.resolve(__dirname, 'scripts/deploy.sh'))
例: cross-platform で安全に使う spawn
異なる OS でも安定して動かすためには、次のように shell: true を使うのが簡単です。
const { spawn } = require('child_process')
const cmd = process.platform === 'win32' ? 'npm.cmd' : 'npm'
const child = spawn(cmd, ['run', 'build'], {
stdio: 'inherit',
shell: true
})
child.on('error', (err) => {
console.error('Spawn failed:', err)
})
これなら Windows・Mac・Linux いずれでも ENOENT が発生しにくくなります。
まとめ
「Error: spawn ENOENT」は Node.js がコマンドを実行できないときに発生する典型的な環境依存エラーです。
原因の多くは「PATH が通っていない」「拡張子の違い」「実行権限がない」といった単純な設定ミスです。
特に次のポイントをチェックすれば、ほとんどのケースで解決できます。
- 絶対パスを指定してみる
- Windows では
.cmd/.exeを意識する shell: trueを使ってシェル解決を有効化する- Docker や CI では PATH と権限を明示的に設定する
開発環境と本番環境で PATH が異なる場合、spawn のような低レベル API よりも execa や cross-spawn といったラッパーライブラリを使うのも実用的です。
参考
- Node.js Docs: child_process.spawn()
- Stack Overflow: Error: spawn ENOENT on Node.js
- cross-spawn: npm package


