npm ciで「Exit handler never called!」エラーが発生したときの対処法

概要

今回はnpm ci を実行したときに発生する「Exit handler never called!」エラーの対処法について紹介していきます。

CI環境やローカルで依存関係を再インストールしようとして npm ci を叩いたら、見慣れない「Exit handler never called!」というメッセージで止まってしまった、という経験はありませんか(- -;

これはnpm自体の内部エラーで、キャッシュの破損や node_modules 側の不整合が原因で発生することが多いです。

対処法はいろいろあると思いますが、少なくともチームで動いている場合は誰かしらはその手順でできているのですよね。。。

自分だけ通らない。。。そういった無いように寄り添った内容となっています(^^b

それではやっていきましょう(^^!

この記事はかなり初心者向けの記事となります。
玄人の方はすでに実施済みの内容が書かれているだけの可能性が高いため「あーね。そりゃそうだ」程度に思っておいてください。

目次

発生するエラーの内容

実際に npm ci を実行すると、以下のようなエラーが出力されます。

コマンド

1
2
3
4
npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error <https://github.com/npm/cli/issues>
npm error A complete log of this run can be found in: [log_folder]

メッセージにも書かれている通り、これはnpm自体の不具合として扱われるエラーです。
ただ実際のところ、手元の環境に残っている壊れたキャッシュや中途半端な node_modules が引き金になっているケースがほとんどです。

そのため、問題を周りに報告する前にまずはローカル側の状態をリセットして再実行するのが定石です(^^b

何もやらずに質問すると無能扱いされるので注意ですよ!

対処法1:npmのキャッシュをクリアする

まず最初に試すべきは、npmのキャッシュを強制的にクリアすることです。

以下のコマンドを実行してください。

コマンド

1
npm cache clean --force

--force を付けないとnpm側で警告が出て実行できない(最近のnpmでは cache clean が既定で保護されているため)ので、必ず付与します。

キャッシュのクリアが終わったら、改めて npm ci を実行します。

コマンド

1
npm ci

これで正常に依存関係のインストールが走れば解決です。

CIサーバーの場合もキャッシュディレクトリを掃除してから再実行する(GitHub Actionsなら actions/cache のキーを変える等)だけで通ることがあります。

対処法2:node_modulesを削除して再インストール

キャッシュクリアでも解消しない場合は、プロジェクト配下の node_modules を丸ごと削除してから再実行します。

依存関係の一部だけが壊れているようなケース(ネットワーク切断時に中途半端にダウンロードされた等)では、キャッシュをクリアしても node_modules 側の壊れたファイルが残り続けるため、こちらの手順が効きます。

Linux / macOSの場合

コマンド

1
2
rm -rf node_modules
npm ci

Windowsの場合

PowerShellなら以下のコマンドで削除できます。

コマンド

1
2
Remove-Item -Recurse -Force node_modules
npm ci

コマンドプロンプトの場合は rmdir /s /q node_modules でもOKです。

node_modulespackage-lock.json の内容に従って完全に再生成されるため、削除しても問題ありません。

もちろんGUIから削除してもOKです(^^b

注意:チーム開発の場合、package-lock.jsonは絶対に削除しないこと

ここが今回一番伝えたいポイントです。

package-lock.jsonは絶対に削除しないでください。

AIに質問してみると「気軽に消していいよ」見たいなことを言われることがありますが、チーム開発の現場では非常に危険です。

理由は以下の通りです。

  • npm cipackage-lock.json に記載された正確なバージョンで依存関係を再現するコマンドです。
  • lockファイルが無いと npm ci 自体が動かず、代わりに npm install を使うしかなくなる
  • npm installpackage.json のバージョン範囲から最新のものを取ってくるため、知らないうちに依存関係のバージョンが変わってしまう
  • 結果として「ローカルでは動いていたのに本番だけ壊れる」という事故の原因になる

また意図しないバージョンのインストールによりセキュリティインシデントが発生する可能性があります。

非常に危険です。

エラーが出ているからといって、再現性の要である package-lock.json を消す方向に走らないようにしましょう。

lockファイルの更新が必要な場合は、意図的に npm install <パッケージ名> を叩いて差分を取るのが正しい流れです。
「エラー回避のために消す」というのは、依存関係管理の根幹を崩す行為になるので避けてください。

まとめ

今回の対処フローを整理すると、以下の順番になります。

  • 手順1npm cache clean --force でキャッシュをクリアして npm ci を再実行
  • 手順2:それでもダメなら node_modules を削除して npm ci を再実行
  • 禁止事項package-lock.json絶対に削除しない

Exit handler never called! はnpm内部のエラー表示ですが、実際はローカル側のキャッシュや node_modules を掃除するだけで直るケースがほとんどです。

焦って package-lock.json を消してしまうと、あとで依存バージョンの食い違いに悩まされることになるので、今回の手順をそのままたどってみてください(^^

以上となります。
エンジニアは一歩間違えるとすべてを終わらせられるので慎重に行きましょう!
それではお疲れ様です!