npm EACCES "permission denied" on the npm cache - Fix in CI
By Daniel Zoghalchali·Latchkey
EACCES on the npm cache or node_modules means the user running npm cannot write where it needs to. In CI and Docker this is almost always a directory owned by root from an earlier step.
What this error means
npm fails while writing to ~/.npm/_cacache or node_modules with "EACCES: permission denied". It frequently appears after a step ran as root (or a cached layer was created as root) and a later step runs as a non-root user.
A previous step (often a Docker build run as root, or a sudo npm call) created ~/.npm or node_modules owned by root. When the build user runs npm next, it cannot write there.
Installing globally without permission
npm install -g writes to a system prefix the CI user cannot modify. Global installs as non-root commonly hit EACCES.
How to fix it
Fix ownership of the cache and modules
Hand the npm directories back to the current user.
Do not run sudo npm install - it leaves root-owned files behind.
Use a user-writable global prefix (npm config set prefix ~/.npm-global) or npx instead of global installs.
In Dockerfiles, run npm as the same user that runs the build, not root.
How to prevent it
Never mix root and non-root npm runs in the same workspace.
Set a user-writable npm prefix for global tools.
Bake correct ownership into base images.
Frequently asked questions
What causes ""EACCES: permission denied""?
A previous step (often a Docker build run as root, or a sudo npm call) created ~/.npm or node_modules owned by root. When the build user runs npm next, it cannot write there.
How do I fix "EACCES: permission denied"?
Hand the npm directories back to the current user.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.