Skip to content
Latchkey

npm EACCES Permission Denied in CI - Fix File and Cache Permissions

EACCES means npm tried to write to a path it does not own. In CI this is usually a cache directory or a global install location with mismatched ownership, often from running as a different user inside a container.

What this error means

npm install fails with code EACCES and a permission denied syscall on a path under ~/.npm, /usr/lib/node_modules, or the project directory. It frequently appears when the job switches users between steps or mounts a volume owned by root.

npm
npm ERR! code EACCES
npm ERR! syscall mkdir
npm ERR! path /usr/lib/node_modules/foo
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, mkdir '/usr/lib/node_modules/foo'

Common causes

The npm cache or install dir is owned by another user

A cache populated as root cannot be written by a non-root job step, producing permission-denied errors mid-install.

Global install into a system path without rights

Installing a package globally writes to /usr/lib or /usr/local, which the CI user often cannot modify.

How to fix it

Fix ownership of the cache and project

  1. Chown the npm cache and working directory to the running user.
  2. Re-run the install.
Terminal
sudo chown -R "$(id -u):$(id -g)" ~/.npm "$PWD"
npm ci

Avoid global installs that need root

  1. Install tools as devDependencies and call them via npx or package scripts.
  2. Or set a user-writable npm prefix instead of a system path.
Terminal
npm config set prefix "$HOME/.npm-global"

How to prevent it

  • Run all npm steps as a consistent user, keep the cache in a user-owned path, and prefer local devDependencies over global installs so no step needs elevated permissions.

Related guides

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