Skip to content
Latchkey

Node.js "spawn EACCES" - Script Not Executable in CI

Node tried to execute a file that does not have the executable permission bit, so the OS denied the spawn. In CI this commonly happens to scripts whose +x bit was lost in checkout or packaging.

What this error means

A step that runs a local script or binary fails with spawn EACCES. The file exists, but it is not marked executable, often because git did not preserve the executable bit.

node
Error: spawn EACCES
    at ChildProcess.spawn (node:internal/child_process:421:11)
  errno: -13,
  code: 'EACCES',
  syscall: 'spawn ./scripts/build.sh'

Common causes

The script lacks the executable bit

A .sh or binary checked in without +x (or unpacked from an archive that dropped permissions) cannot be spawned directly.

Spawning a directory or non-executable target

Passing a path that is a directory or a non-runnable file to spawn yields EACCES rather than a not-found error.

How to fix it

Mark the script executable

Add the executable bit and commit it so git preserves the mode.

Terminal
chmod +x scripts/build.sh
git update-index --chmod=+x scripts/build.sh

Invoke the interpreter directly

Run the script through its interpreter so the executable bit is not required.

workflow
node scripts/build.js
# or
bash scripts/build.sh

How to prevent it

  • Commit scripts with the executable bit set (git update-index --chmod=+x).
  • Prefer invoking via an interpreter in CI to sidestep mode loss.
  • Verify file modes after unpacking archives that may drop permissions.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →