Node.jsで「Cannot find module」が出たとき:AI生成コードの原因を順に確かめる
AIを使いこなすClaudeで執筆し、GPTで自動校閲・修正しています。

AIが書いたコードを動かして「Cannot find module」が出たら、まずエラー文の引用符の中を見てください。代表的な確認先は、次の3つです。 • 'express' のように ./ で始まらない名前なら、パッケージが入っていない可能性が高いです。 • './utils' や '../lib/db' のようにパスなら、ファイルの場所・名前・拡張子を疑います。 • パスも名前も合っていそうなら、CommonJS(require)とESM(import)の違いを見ます。パッケージが公開していない場所を読むと、通常は別のエラーコード ERR_PACKAGE_PATH_NOT_EXPORTED になります。 この記事では、この見分け方を早見表にし、最後にAIへ質問するときの依頼文も載せます。なお、本文のエラー文やコードは説明用の例で、実際に実行した出力ではありません。Nodeのバージョンによって文面は変わることがあるので、引用符の中身と「どのファイルから読もうとしたか」に注目してください。
1. エラー文のどこを見るか
次のような出力を想定します(説明用の例)。
Error: Cannot find module 'express'
Require stack:
- /home/user/app/server.js読む場所は2つです。
- 引用符の中:探している名前です。
- Require stack(または "imported from" の後):その名前を書いているファイルです。AIに見せるときも、ここは必ず含めます。
Node.jsの公式ドキュメントでは、require() は相対パス(./ ../)と、先頭に付かない名前(bare specifier)を区別して解決すると説明されています。相対パスは読み込む側のファイルの場所が基準で、名前だけの指定は node_modules フォルダを上の階層へたどりながら探します(Node.js: Modules (CommonJS))。引用符の中が名前なのかパスなのかで、調べる場所が分かれるのはこのためです。
2. 原因別の早見表
- express など名前、疑う原因:未インストール、確認コマンド(macOS/Linux):ls node_modules/express、直し方:npm install express
- 同上、package.json にも無い、疑う原因:AIが依存関係を書き忘れた、確認コマンド(macOS/Linux):cat package.json、直し方:入れたうえで package.json に載ったか確認
- 同上、入っているのに出る、疑う原因:実行場所が違う/別フォルダの node_modules、確認コマンド(macOS/Linux):pwd と ls、直し方:package.json のあるフォルダへ移動して実行
- ./utils などパス、疑う原因:ファイル名・場所の違い、確認コマンド(macOS/Linux):ls(対象フォルダ)、直し方:実在する名前・場所に合わせる
- ./utils(ESMの import)、疑う原因:拡張子の省略、確認コマンド(macOS/Linux):ファイル冒頭が import か確認、直し方:./utils.js と拡張子を書く
- ERR_PACKAGE_PATH_NOT_EXPORTED、疑う原因:パッケージが公開していない場所、確認コマンド(macOS/Linux):各パッケージの package.json の exports、直し方:公開されている入口から読む
Windowsでは ls を dir、cat を type、node_modules/express を node_modules\express に読み替えてください。
未インストールの場合
node_modules に該当フォルダが無ければ、入れるだけです。AIが提示したコマンドの npm install 名前 をそのまま実行する前に、パッケージ名が実在するかも確認してください。AIは存在しない名前や似た名前を出すことがあり、見知らぬ名前を入れるのは安全面でも避けたいところです。公式サイトやnpmの公開ページで、名前と提供元を確かめてからにしましょう。
パス・拡張子の場合
相対パスは、実行したフォルダではなく、require や import を書いたファイルの位置が基準です(前掲のModulesドキュメント)。AIが「src/ の中のファイル」を前提にパスを書いたのに、実際は別の階層に置いていた、というずれがよく起こります。大文字小文字の違いも、環境によって通ったり通らなかったりするので、ファイル名と完全に一致させてください。
3. モジュール形式の違いで起きるもの
ここが「パスは合っているのに出る」ケースの本命です。公式ドキュメントによると、CommonJSの require は拡張子を省略でき、.js .json .node の順に探します。フォルダを指定すれば index.js なども探します。一方ESMの import では、相対・絶対指定に拡張子が必須で、./dir/ のようなディレクトリindexの省略もできません(Node.js: ECMAScript modules)。
つまり、AIがCommonJSの感覚で書いた次のコードを、ESMとして動かすと失敗します(説明用の例)。
// app.mjs(ESMとして扱われる)
import { add } from './utils'; // 拡張子なし → 見つからない
import { add } from './utils.js'; // こう書くNodeがファイルをESMとCommonJSのどちらで扱うかは、明示指定があればそれに従います。.mjs と最も近い package.json の "type": "module" はESM、.cjs と "type": "commonjs" はCommonJSです。明示指定がない .js の扱いはNode.jsのバージョンによって異なり、現行版では import export などの構文から判定されます(Node.js: ECMAScript modules、Node.js: Packages)。
確認手順はシンプルです。package.json に "type": "module" があるか、ファイル拡張子が .mjs か .cjs かを見てください。AIのコードが require なのに "type": "module" だったり、逆に import なのに type 未指定だったりしたら、形式の食い違いです。どちらかに統一します。
補足:require と ESM の組み合わせ
Node.js 22以降の公式ドキュメントでは、require() で同期的なESM(トップレベル await を含まないもの)を読み込めると説明されています。トップレベル await を含む場合は ERR_REQUIRE_ASYNC_MODULE となり、import() を使うよう案内されています(Modules (CommonJS))。古いNodeでは同じ書き方が通らない可能性があるため、node -v の結果は必ずAIに伝えてください。
補足:公開されていない場所を読んでいる
パッケージの package.json に exports があると、書かれていない内部パスは読み込めず、ERR_PACKAGE_PATH_NOT_EXPORTED が出ます(Node.js: Packages)。これは「Cannot find module」とは別のエラーです。pkg/dist/internal.js のような深いパスをAIが書いていたら、READMEにある公開用の読み込み方に直します。
4. 調べる順番(3分チェック)
- 引用符の中が名前か、パスかを見る。
- node -v と pwd を確認する。
- 名前なら ls node_modules/名前 と cat package.json。
- パスなら、Require stack に出たファイルを開いて、指定先が実在するか ls で確認する。
- import と require の混在、"type"、拡張子を見る。
- それでも解決しなければ、次の依頼文でAIに渡す。
5. AIへの伝え方
「エラーが出ました、直して」だけでは、AIは推測で別のコードを書きがちです。次の形で、事実を分けて渡してください。
Node.jsで次のエラーが出ました。原因の候補を可能性の高い順に3つ挙げ、
それぞれ確認用のコマンドを示してください。まだコードは書き換えないでください。
【環境】node -v の結果:v22.x(実際の値に置き換え)/OS:(例)macOS
【実行コマンド】node server.js
【エラー全文】
(Require stack を含めて貼る)
【package.json】
(dependencies と "type" の部分)
【該当ファイルの先頭10行】
(import / require の行を含める)
【フォルダ構成】
(ls の結果)回答に出た確認コマンドは、自分で実行して結果をAIに返してください。AIが「入っているはず」と言っても、ls node_modules/名前 の結果が事実です。
渡す前に、APIキーやパスワード、社内のフォルダ名やユーザー名は伏せ字にしてください。.env の中身は貼らないでください。エラー文のパスには自分のユーザー名が含まれることがあります。
6. それでも直らないとき
- node_modules を消して npm install し直す方法は有効なことが多いですが、package.json の内容が間違っていれば同じ結果になります。先に中身を確認してください。
- AIが一度に複数ファイルを書き換えた場合は、直前の動いていた状態に戻して、1つずつ試してください。
- エラー文の引用符の中が、毎回同じ名前でなく変わっていく場合は、順番に依存関係が足りていない可能性があります。AIに「このファイルが読み込んでいる名前を全部列挙して」と頼み、package.json と突き合わせると早く片づきます。

