Python Error: ModuleNotFoundError — No Module Named
Traceback (most recent call last):
File "/Users/dev/project/app.py", line 3, in <module>
import requests
ModuleNotFoundError: No module named 'requests'
ModuleNotFoundError is Python’s clearest error. The interpreter looked for a module on sys.path, didn’t find it, and stopped. The fix is almost always one of two things: you installed into a different Python than the one running your code, or your local code isn’t on sys.path. Both are diagnosable in 30 seconds with python -m pip list and python -c 'import sys; print(sys.path)'.
The single rule that prevents 90% of Python environment pain: always use python -m pip instead of bare pip. It guarantees the install and the run use the same interpreter, eliminating the most common variant of this error.
Why this happens
- Wrong virtualenv (or no venv at all). You activated a venv, then opened a new shell that didn't inherit it. Or your IDE runs the system Python while your terminal uses the project's venv. `pip install requests` went to one Python; `python app.py` ran a different one.
- pip vs python version mismatch. You ran `pip install` (which points to one Python, often the system one) but invoked `python3` (a different one). On macOS especially, `python` may be 3.9 (Apple-shipped) and `python3` may be 3.11 (Homebrew). The fix is `python -m pip install <pkg>` — that always uses the same Python.
- Project not installed editably / wrong PYTHONPATH. Your imports use `from myapp.utils import …` but `myapp` is your local code, not on sys.path. Either the project isn't `pip install -e .`'d, or you're running from a directory that doesn't have `myapp` as a subfolder.
- Missing __init__.py in a package directory. In Python 3.3+ namespace packages don't need `__init__.py`, but mixing namespace and regular packages, or having a stray empty directory, breaks imports. If `myapp/utils.py` works but `from myapp.utils import x` doesn't, look for missing `__init__.py`.
- Module installed but for a different Python or platform. You're inside Docker / a container with a different Python build (alpine vs slim, 3.10 vs 3.12) than your host. The host has `requests` installed; the container doesn't. Or you copied `site-packages` between architectures and binary wheels (numpy, pandas) don't load.
How to fix it
Fixes are ordered by likelihood. Start with the first one that matches your context.
1. Install with `python -m pip` so install and run use the same interpreter
Bare `pip install` uses whichever pip is first on PATH — often not the one matched to the Python you'll run. `python -m pip install` is the canonical, always-correct form.
# Confirm which Python you'll actually run:
which python
python --version
# Install into THAT interpreter, not the system one:
python -m pip install requests
# Verify it's actually importable from that Python:
python -c "import requests; print(requests.__version__)"
2. Use a virtualenv per project
Don't install project dependencies into your system Python. Create a venv per project; activate it; install there; never confuse "which Python" again.
# Create + activate a venv (Python 3.11+):
python -m venv .venv
source .venv/bin/activate # macOS/Linux
# .venv\Scripts\activate # Windows PowerShell
# Install your dependencies:
python -m pip install -r requirements.txt
# Confirm the venv is active:
which python # should print .../.venv/bin/python
python -m pip list
3. Install your own project as editable
For local code (`from myapp.foo import bar`), make your project pip-installable and install it in editable mode. Edits to source take effect immediately, and your `myapp` package is always on sys.path.
[project]
name = "myapp"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = [
"requests>=2.31",
"pydantic>=2",
]
[build-system]
requires = ["setuptools>=68"]
build-backend = "setuptools.build_meta"
[tool.setuptools.packages.find]
where = ["src"]
4. Check sys.path and PYTHONPATH
If a module is installed but not importable, look at `sys.path` to see what Python is searching. If your project root or src/ isn't there, fix the launch (cwd, PYTHONPATH, or pip install -e).
import sys, os, site
print("python:", sys.executable)
print("version:", sys.version)
print("cwd:", os.getcwd())
print("PYTHONPATH:", os.environ.get('PYTHONPATH'))
print("site-packages:")
for p in site.getsitepackages():
print(" ", p)
print("sys.path:")
for p in sys.path:
print(" ", p)
5. Use a tool that pins Python+deps together
`uv`, `poetry`, or `pipenv` lock the Python version and dependency tree together. Eliminates a whole class of "works on my machine" Python issues. `uv` is the fastest as of 2025+ and a drop-in for `pip` + `venv`.
Detection and monitoring in production
Add `python -c "import myapp; import otherdeps"` as a smoke test in CI on every PR — ModuleNotFoundError is deterministic and trivially catchable. For Docker images, run the smoke test as a `RUN` in the build (not just at container startup) so a missing dep fails the build, not the deploy. Track ModuleNotFoundError in production logs by exception class; in healthy services it should be zero.
Related errors
- nextjsmodule_not_foundThe Next.js build (webpack/Turbopack) tried to resolve an import path and couldn't find it. Either the package isn't installed, the relative path is wrong, a TypeScript path alias isn't mirrored in `tsconfig.json` and `next.config.js`, or the file's case differs between disk and import (Linux is case-sensitive, macOS isn't).
- nodejsERR_REQUIRE_ESMYour CommonJS file used `require('some-package')` but the package is now ESM-only (its `package.json` has `"type": "module"` or `"exports"` only points to `.mjs`). Node's CJS loader can't synchronously load an ESM module.
- postgresECONNREFUSEDYour application tried to open a TCP connection to Postgres and the OS rejected it — Postgres isn't listening on the host:port you specified, or a firewall blocked the connection.
- kubernetesImagePullBackOffThe kubelet failed to pull the container image and is now backing off retry attempts. Underlying error is one of ErrImagePull, ImagePullBackOff is the recovery loop. Causes are almost always image name/tag wrong, registry auth missing, registry rate-limit, or the image genuinely doesn't exist for the node's architecture.
- kubernetesCrashLoopBackOffYour container starts, exits with a non-zero code (or is OOMKilled), the kubelet restarts it, it exits again — repeat. After several quick failures the kubelet enters CrashLoopBackOff, an exponential delay between restart attempts so you don't melt the node.
Frequently asked questions
I installed the package with pip, why does Python still say no module named? +
What's the difference between ModuleNotFoundError and ImportError? +
Why does VS Code show no error but `python app.py` fails with ModuleNotFoundError? +
How do I make sure my Docker image has the right Python deps? +
My import works at the top of one file but fails in another in the same project. +
Should I add my project to PYTHONPATH instead of pip install -e? +
I get ModuleNotFoundError for a module that exists in my file tree. +
Does `pip install --user` cause ModuleNotFoundError? +
When to escalate to Python support
ModuleNotFoundError is configuration, not a Python interpreter bug. Before filing upstream, confirm: (a) you can reproduce in a fresh venv with `python -m pip install <only_the_failing_pkg>`, (b) the package's wheel matches your platform (architecture, libc), and (c) `pip show <pkg>` shows it installed where you expect. If a package's published wheel really is broken on your platform, file with the package maintainer with `python --version` and `pip --version` output.