Learning objectives
After reading this article you will be able to:
- Tell a missing package apart from a wrong file path
- Fix the Node.js and Python versions of the error step by step
- Prevent the error from coming back on the next deploy
On this page
Your app started fine on your computer, you deployed it, and the log ends with one of these:
Error: Cannot find module 'express'
Require stack:
- /app/index.js
at Module._resolveFilename (node:internal/modules/cjs/loader:1517:15)
...
at Module._compile (node:internal/modules/cjs/loader:1871:14) {
code: 'MODULE_NOT_FOUND',
requireStack: [ '/app/index.js' ]
}ModuleNotFoundError: No module named 'discord'Both messages say the same thing: an import or require named something the runtime could not locate. The fix is almost never mysterious, but you have to read the message before guessing. The name inside the quotes tells you which of two families of problem you have.
What do these errors actually mean?#
In Node.js, require() throws MODULE_NOT_FOUND when the path or package does not exist. The ES module version, import, throws ERR_MODULE_NOT_FOUND. In Python, ModuleNotFoundError is a subclass of ImportError, raised when a module could not be located (Python docs).
Here is the ES module form, for a missing package and for a relative file:
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'express' imported from /app/index.js
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/app/utils' imported from /app/index.js
Did you mean to import "./utils.js"?Look at what the name looks like:
- A bare name (
express,discord): a package that is not installed where the app runs. - A path (
./utils,/app/utils): a file the runtime could not find at that exact location.
Everything below follows that split.
Is the package missing from dependencies?#
This is the most common cause. For a bare package name, Node.js starts in the folder of the current file, looks in node_modules, then walks up through the parent folders until the root of the file system (Node.js docs). If no node_modules on that path contains the package, you get the error.
Check these in order:
- Is it in
package.json? If you installed it withnpm install expressit is listed. If you copied code from a tutorial and never installed it, it is not. - Is it in
devDependenciesonly? npm saysdependenciesis for runtime packages anddevDependenciesis for tools that users of your module do not need, such as test harnesses and transpilers (npm docs). A production install can skip dev packages, andnpm ciomits them by default whenNODE_ENVisproduction(npm docs). If your app imports it at runtime, move it:
npm install --save-prod express- Did the install actually run on the server? Uploading the
node_modulesfolder from your PC is not reliable. Shippackage.jsonplus the lockfile and install from them.
npm ci is the right command for a clean install. It requires an existing package-lock.json, deletes any existing node_modules, and exits with an error instead of updating the lockfile when package.json and the lockfile disagree. That last behavior is useful: it turns a silent mismatch into a loud failure.
npm ci
node index.jsIf npm ci fails because the lockfile is out of sync, run npm install locally, commit the updated lockfile, and deploy again.
Is the file path, case or extension wrong?#
When the name is a path, the cause is a file that is not where the import says it is.
Letter case. On Linux, ./Utils.js and ./utils.js are two different files. Windows and macOS file systems usually ignore case, so an import with the wrong case works on your machine and fails on the server. Rename the file or fix the import so they match exactly. If you rename only the case of a file, make sure your Git client records the change, because some setups ignore it.
Missing extension in ES modules. With import, relative specifiers need the extension, and directory indexes must be fully specified (Node.js ESM docs). This works with require in CommonJS but not with import:
// Fails in an ES module: ERR_MODULE_NOT_FOUND
import { helper } from "./utils";
// Works
import { helper } from "./utils.js";
import { setup } from "./startup/index.js";Your app is an ES module when package.json has "type": "module" or the file ends in .mjs. If you are using TypeScript with a bundler locally, imports without extensions may work there and break when you run the output directly.
A file that was never uploaded. Check that the file is in your ZIP or commit. Common culprits are a .gitignore line or an upload that skipped a folder. In a monorepo, a shared package that sits outside the folder you deployed will be missing too.
Is the main file or build output wrong?#
Some projects compile to a dist or build folder. If your start command points at dist/index.js and the build step never ran, or dist is ignored by version control, the entry point itself is missing:
Error: Cannot find module '/app/dist/index.js'Confirm three things: the build command runs before start, the output folder is part of what you deploy (or is produced on the server), and the main file in your configuration matches the real path. Also check "main" in package.json if you import the package by name, since a missing or unresolvable main with no index.js reports the whole module as missing (Node.js docs).
Why does Python say "No module named"?#
The Python version has its own set of causes.
The package is not installed. Install it, and record it so the next environment gets it too:
python -m pip install discord.py
python -m pip freeze > requirements.txtThen on the target, python -m pip install -r requirements.txt. The pip docs describe this freeze-then-install flow, and also note that pip freeze does not compute a lockfile or a solver result (pip docs). For a fully pinned setup, use a lockfile tool.
The import name differs from the install name. This trips up many people:
| You write | You install |
|---|---|
import yaml |
PyYAML |
import PIL |
Pillow |
import cv2 |
opencv-python |
import dotenv |
python-dotenv |
import discord |
discord.py |
Wrong interpreter. pip and python can belong to different installs. Use python -m pip install ... so the package goes to the interpreter that will run your code. Inside a virtual environment, activate it first.
A local file shadows or misses the module. A file named discord.py or random.py in your project can hide the real package. For your own modules, check that the folder layout matches the import and that you run the app from the expected working directory.
How do you diagnose it quickly?#
Start from the message:
- Copy the exact module name from the log.
- Bare name? Run
npm ls express(Node.js) orpython -m pip show discord.py(Python) in the same environment that runs the app. - Path? List the folder and compare the name character by character, including case and extension.
- Still stuck? Run the failing import in isolation:
node -e "require.resolve('express')"
node --input-type=module -e "await import('express')"
python -c "import discord; print(discord.__file__)"require.resolve throws MODULE_NOT_FOUND when it cannot find the module, so it shows what the runtime sees without starting your whole app.
One more Node.js case: require() can load an ES module only if it has no top-level await, otherwise it throws ERR_REQUIRE_ASYNC_MODULE (Node.js docs). That is a different error, but it shows up in the same place. Switch to import() in that situation.
How do you stop it from coming back?#
- Treat the lockfile as part of the code: commit
package-lock.json, and usenpm cifor installs. - Keep runtime packages in
dependencies. - Name files in lowercase and import them with the exact same spelling.
- In ES modules, always write the extension.
- Pin Python packages in
requirements.txtand install with the same interpreter that runs the app. - Test the deployed shape locally: delete
node_modules, runnpm ci, then start the app. If it fails there, it will fail on the server.
For related deploy failures, see how to read build errors, how to read app logs and how to host a Node.js app.
How to do this on Square Cloud#
On Square Cloud you deploy by uploading a ZIP, using the CLI, pushing to GitHub or using the VS Code extension. Whichever you pick, the first check is the same: open the real-time logs, copy the module name from the error, and compare it with the files you actually uploaded. On start, the platform runs npm install when there is no node_modules, with NODE_ENV=production: a package that is only in devDependencies is not installed and causes this error.
The in-browser file manager shows the files in your application, so you can confirm that the path in the error exists and that its letter case matches. The editor saves straight to the application without a redeploy.
If the error names your entry file, check that the main file setting points to a file that exists. That setting lives in squarecloud.app, which is optional: the dashboard can generate it on deploy (runtime, memory, main file), or you can write it at the project root. There is no build step, so an entry point in dist means uploading the compiled folder or putting the build in your start command.
Once you have the fix locally, send it with the CLI commit command or by pushing to GitHub through the official GitHub Action, which can run commit --restart on every push. The CLI page walks through the commit workflow.
Deploy
Push from GitHub, the CLI or a ZIP and go live in seconds
FAQs
What is the difference between MODULE_NOT_FOUND and ERR_MODULE_NOT_FOUND?
MODULE_NOT_FOUND is the code Node.js sets when require() (CommonJS) cannot resolve a path. ERR_MODULE_NOT_FOUND is the code for the same failure with import (ES modules). The causes overlap, but ES modules also require a full file extension on relative imports.
Why does my app work on my PC but fail with 'Cannot find module' after deploy?
Your machine has files and packages the deployed copy does not: a globally installed package, a node_modules folder you never upload, a package that is only in devDependencies, or a file whose name differs in letter case. Linux treats Utils.js and utils.js as different files, Windows and macOS usually do not.
Does ModuleNotFoundError mean I should run pip install?
Usually, but check the package name first. The import name and the install name often differ: import yaml comes from PyYAML, import PIL from Pillow, import cv2 from opencv-python. Also confirm pip installs into the same Python interpreter that runs your app.
Should I upload my node_modules folder?
No. Ship package.json and the lockfile, and install on the target with npm ci or your package manager's equivalent. A node_modules folder built on another operating system can contain binaries that do not run elsewhere.
More in Deploy
See all 33 articles- What are environment variables?Environment variables are key-value pairs the operating system hands to a process at startup. Learn to read them in Node.js and Python and keep tokens out of code.
- What is a deployment?A deployment takes a version of your code to a server, prepares it and starts it. See the stages, the methods and how to roll back when it goes wrong.
- How much RAM and CPU does my app need?Size RAM and CPU by measuring your app's real peak and adding about 30% headroom. Learn how to measure in Node.js, Python and Java and what to do if short.
- Automatic deploys with GitHub ActionsAutomatic deploys with GitHub Actions ship your code to the server on every push. See the workflow step by step, secrets, tests before deploy and common errors.