npm EPERM "operation not permitted" - Fix Locked/Read-Only Files in CI
EPERM means the operating system refused a file operation npm attempted - usually an unlink or rename inside node_modules. The file is locked, read-only, or owned by a user npm is not running as.
What this error means
npm fails with npm error path ... and EPERM: operation not permitted, unlink/rename. It is common on read-only mounts, root-owned files in Docker, or when another process holds the file.
npm error code EPERM
npm error syscall unlink
npm error path /app/node_modules/.staging/esbuild-XXXX
npm error errno -1
npm error Error: EPERM: operation not permitted, unlink '/app/node_modules/...'Common causes
Files owned by another user (root) or read-only
A node_modules created by root (or on a read-only mount) cannot be modified by the non-root build user, so unlink/rename is denied.
A file held by another process
An antivirus, file watcher, or a parallel step holding a handle to a file under node_modules blocks npm from replacing it.
How to fix it
Fix ownership and start clean
Hand node_modules back to the build user and reinstall on a writable path.
sudo chown -R "$(id -u):$(id -g)" node_modules 2>/dev/null || true
rm -rf node_modules
npm ciRemove contention and read-only mounts
- Ensure no other step or watcher is touching node_modules during install.
- Install into a writable directory, not a read-only volume.
- In images, run npm as the same user that owns the workspace.
How to prevent it
- Keep node_modules owned by the build user.
- Install on writable layers/mounts only.
- Avoid concurrent processes touching node_modules.