npm コマンドのローカル/グローバル実行が “EACCES: permission denied”となる場合の対処

2023.12.04

こんにちは、CX 事業本部 Delivery 部の若槻です。

Node.js のパッケージ管理マネージャーである npm のコマンド実行が EACCES: permission denied というエラーとなる場合があります。

この問題の原因としては Node.js の新しいバージョンをローカルにインストールした際に、ユーザーのアクセス権が無いディレクトリが依存関係の保管領域やインストール時の一時領域として設定されてしまうためです。

解決方法は主に次の 3 つが上げられます。

  1. Node 管理マネージャー(nvmn など)を使用して npm を再インストールする。
  2. npm のデフォルトディレクトリを変更する。
  3. ディレクトリにユーザーアクセス権を付与する。

上 2 つの解決方法は下記の公式ドキュメントで紹介されている方法で、推奨されているのは 1 つ目の方法です。一方でパーミッションエラーが発生する確率を最小限にする方法は 2 つ目の方法ともされています。

今回は、npm コマンドのローカル/グローバル実行が EACCES: permission denied となる問題を、2 または 3 の方法で解決してみました。

環境

$ sw_vers
ProductName:            macOS
ProductVersion:         14.1.1
BuildVersion:           23B81

ローカル実行時の EACCES を、ユーザーアクセス権付与で解決する

コマンド実行が EACCES: permission denied エラーとなる

次のようにnpm install のローカル実行が EACCES: permission denied となっています。

$ npm i
npm ERR! code EEXIST
npm ERR! syscall rename
npm ERR! path /Users/wakatsuki.ryuta/.npm/_cacache/tmp/15a58437
npm ERR! dest /Users/wakatsuki.ryuta/.npm/_cacache/content-v2/sha512/c2/6c/e6d7fd8dce970254202c1aaaa24c12bec4dc8b990c133aaeb7adc5ba79eaba81838ed1cc9365138e91546baec2963c18a0ad21451ef0eb12fa2738cb4a02
npm ERR! errno -13
npm ERR! EACCES: permission denied, rename '/Users/wakatsuki.ryuta/.npm/_cacache/tmp/15a58437' -> '/Users/wakatsuki.ryuta/.npm/_cacache/content-v2/sha512/c2/6c/e6d7fd8dce970254202c1aaaa24c12bec4dc8b990c133aaeb7adc5ba79eaba81838ed1cc9365138e91546baec2963c18a0ad21451ef0eb12fa2738cb4a02'
npm ERR! File exists: /Users/wakatsuki.ryuta/.npm/_cacache/content-v2/sha512/c2/6c/e6d7fd8dce970254202c1aaaa24c12bec4dc8b990c133aaeb7adc5ba79eaba81838ed1cc9365138e91546baec2963c18a0ad21451ef0eb12fa2738cb4a02
npm ERR! Remove the existing file and try again, or run npm
npm ERR! with --force to overwrite files recklessly.

npm ERR! A complete log of this run can be found in: /Users/wakatsuki.ryuta/.npm/_logs/2023-12-04T04_43_13_495Z-debug-0.log

一時領域として使用している /Users/$USER/.npm/_cacache ディレクトリへのアクセスがなぜか失敗するようになっているようですね。

解決

次のように chown(change owner)コマンドで /Users/$USER/.npm/_cacache ディレクトリのアクセス権をユーザーに付与します。-R オプションは --recursive オプション略です。

sudo chown -R $USER /Users/$USER/.npm/_cacache

ローカルコマンドが正常に実行できるようになりました。

$ npm i
npm WARN deprecated @types/axios@0.14.0: This is a stub types definition for axios (https://github.com/mzabriskie/axios). axios provides its own type definitions, so you don't need @types/axios installed!
npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.

added 652 packages, and audited 690 packages in 9s

134 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

グローバル実行時の EACCES を、デフォルトディレクトリの変更で解決してみる

コマンド実行が EACCES: permission denied エラーとなる

次のようにグローバル実行した npm install コマンドが EACCES: permission denied となっています。

$ npm i -g aws-cdk-lib
npm ERR! code EACCES
npm ERR! syscall mkdir
npm ERR! path /usr/local/lib/node_modules/aws-cdk-lib
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/aws-cdk-lib'
npm ERR!  [Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/aws-cdk-lib'] {
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   syscall: 'mkdir',
npm ERR!   path: '/usr/local/lib/node_modules/aws-cdk-lib'
npm ERR! }
npm ERR! 
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR! 
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.

npm ERR! A complete log of this run can be found in: /Users/wakatsuki.ryuta/.npm/_logs/2023-12-04T04_47_37_276Z-debug-0.log

解決

npm をグローバル実行するための領域として ~/.npm-global ディレクトリを作成します。私の環境ではすでに作成されていました。

$ mkdir ~/.npm-global
mkdir: /Users/wakatsuki.ryuta/.npm-global: File exists

npm コマンドのプレフィクスを ~/.npm-global に設定します。

npm config set prefix '~/.npm-global'

このコマンドは npm config set <key>=<value> [<key>=<value> ...] という構文で、prefix~/.npm-global を設定しています。

次のコマンドを実行して、グローバルの実行可能ファイル ~/.npm-global/bin を PATH に追加します。

echo "export PATH=~/.npm-global/bin:$PATH" >> ~/.profile

グローバルコマンドが正常に実行できるようになりました。

$ npm i -g aws-cdk-lib

added 5 packages in 3s

3 packages are looking for funding
  run `npm fund` for details

おわりに

npm コマンドのローカル/グローバル実行が EACCES: permission denied となる場合の対処について紹介しました。

私同様このエラーに時々遭遇する人は多いのではないでしょうか。焦らず確実に対処するようにしましょう。

参考

以上