npm tried to read or write a file it cannot access (package-lock, cache tarball, or global path). Fix ownership/locks on that path or move npm to user-owned locations before retrying.
Fixes npm ERR! Error: EACCES: permission denied, open '<path>'
# copy the path from the error
stat <path>
ls -l <path># copy the path from the errorstat <path>ls -l <path>npm ERR! Error: EACCES: permission denied, open '<path>'
On this page
The fs.open call failed because the target file is not readable/writable by the current user. npm often hits this when opening package-lock.json, cache tarballs, or global install paths that are root-owned, read-only, or locked by another process. This happens after mixing sudo and non-sudo installs, cloning into directories with restrictive ACLs, running on WSL2/SMB mounts with Windows permissions, or when antivirus/IDE file watchers hold handles in node_modules. Docker/CI jobs that run as non-root against root-owned volumes see the same EACCES on open.
# copy the path from the error
stat <path>
ls -l <path>sudo chown -R $(whoami) .
# for global prefix you administer
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}npm config set cache ~/.npm-cache
mkdir -p ~/.npm-global
npm config set prefix ~/.npm-global
export PATH="$HOME/.npm-global/bin:$PATH"Close VS Code/terminals holding node_modules, and add a Windows Defender/EDR exclusion for your project and npm cache so files can be opened.
npm cache clean --force
npm cache verifynpm ci
# or
npm installRun inside the workspace you own; avoid sudo unless intentionally installing system-wide.
WSL2 on /mnt/c uses NTFS ACLs that often block POSIX writes; clone to the Linux filesystem (e.g., ~/projects) to avoid EACCES on open. Docker bind mounts inherit host ownership—run the container with matching UID/GID or chown the workspace volume before npm install. On macOS with Homebrew, /opt/homebrew may be admin-only; using nvm/fnm keeps npm files in $HOME and sidesteps system ACLs.