Fixing ModuleNotFoundError in Python
ModuleNotFoundError: No module named 'x' means the Python that is running your script cannot see the package — which is not the same as the package not being installed. On most machines the real cause is that pip installed it into a different Python than the one running the code.
The reliable fix on Windows is to stop using bare pip and install with the same launcher that runs your script: py -m pip install requests. That guarantees the installing Python and the running Python are the same one.
This is the most common error a Python beginner meets, and the standard advice — "just pip install it" — fails precisely in the cases where people get stuck. This guide covers the five actual causes in the order worth checking, with the real error output and the one-line diagnosis for each.
What the error actually says
Traceback (most recent call last):
File "script.py", line 1, in <module>
import requests_fake_xyz
ModuleNotFoundError: No module named 'requests_fake_xyz'
Python searched every folder on its import path and found no package with that name. The name in quotes is what it looked for — read it carefully, because cause #1 lives in that name.
Cause 1: the name is not what you think
Two versions of this, both quick to rule out.
Case matters. Module names are case-sensitive even on Windows, where filenames usually are not. This fails with requests perfectly installed:
>>> import Requests
ModuleNotFoundError: No module named 'Requests'
The install name and the import name can differ. Some well-known packages are installed under one name and imported under another:
| You install | You import |
|---|---|
pip install pillow | import PIL |
pip install beautifulsoup4 | import bs4 |
pip install opencv-python | import cv2 |
pip install scikit-learn | import sklearn |
pip install python-dateutil | import dateutil |
If your missing module is one of these, nothing is broken — the import line just needs the other name.
Cause 2: pip installed into a different Python
The big one. Machines accumulate multiple Pythons — python.org installs, the Microsoft Store version, Anaconda, one bundled with an editor. Bare pip belongs to one of them; your script may run under another.
The machine this article was written on is a live example. py -0p lists every installed interpreter:
-V:3.14 * C:\Python314\python.exe
-V:3.12 C:\Program Files\WindowsApps\PythonSoftwareFoundation...\python3.12.exe
Two Pythons: a python.org 3.14 and a Microsoft Store 3.12. A package pip installs into one is invisible to the other — same machine, same user, different worlds.
Diagnose it in two lines. Ask which Python runs, and which Python pip serves:
py -c "import sys; print(sys.executable)"
py -m pip --version
The pip line names its interpreter explicitly — on this machine, pip 26.2.1 ... (python 3.14). If the path in line one and the version in line two disagree with where your script actually runs, you have found the problem.
The fix that removes the whole class of error: never install with bare pip. Always route through the interpreter you run code with:
py -m pip install requests # Windows launcher
python3 -m pip install requests # macOS / Linux
-m pip means "run the pip that belongs to this Python", which makes a mismatch impossible. Our guide to installing Python on Windows covers why the py launcher is the right habit generally.
Cause 3: your editor runs a different interpreter than your terminal
The variant that produces "it works in the terminal but not in VS Code" (or the reverse). Editors select an interpreter independently of your shell — VS Code shows its choice in the status bar, PyCharm in its settings.
Print sys.executable from inside the failing environment — a line at the top of the script, run through the editor's own Run button:
import sys
print(sys.executable)
If that path differs from the terminal's answer, either point the editor at the interpreter you installed into (VS Code: Ctrl+Shift+P → "Python: Select Interpreter"), or install into the editor's one using the full path it printed: C:\path\to\python.exe -m pip install requests.
Cause 4: the virtual environment is not active
If the project uses a venv, packages live inside it and exist nowhere else. Installing "globally" and then running inside the venv — or the reverse — produces exactly this error.
The tell: your prompt shows (.venv) when the environment is active. If it does not:
.venv\Scripts\Activate.ps1 # Windows PowerShell
source .venv/bin/activate # macOS / Linux
Then install while it is active, so the package lands inside. The venv documentation covers the mechanics; the habit that prevents confusion is one venv per project, activated before any pip command.
Cause 5: your own file is shadowing the package
The sneaky one. A file in your project named the same as a library — requests.py, random.py, email.py — gets imported instead of the real package, because your script's own folder is searched first.
The error is usually not ModuleNotFoundError itself but its cousin: AttributeError: module 'requests' has no attribute 'get' — the import "succeeded" but found your near-empty file. Check what was actually imported:
import requests
print(requests.__file__)
If that prints a path inside your own project, rename your file. Also delete the stale __pycache__ folder next to it, which can keep the shadow alive after the rename.
The checklist, in order
- Spelling and case of the import, and whether the install name differs (pillow → PIL).
py -m pip installinstead of bare pip — rules out the multiple-Pythons trap in one move.print(sys.executable)inside the failing context, compared with where you installed.- Is the venv active? Look for the prefix on your prompt.
print(module.__file__)— are you importing your own file by accident?
Steps 2 and 3 resolve the large majority of real cases. The pip user guide is the reference for the rest.
Frequently asked questions
Why do I get ModuleNotFoundError after pip install succeeded?
Because pip installed into a different Python than the one running your script — the most common cause on machines with more than one Python, which is most machines. Install with py -m pip install (Windows) or python3 -m pip install so the installing and running interpreter are guaranteed to be the same.
How do I check which Python my script is using?
Add import sys; print(sys.executable) to the top of the script and run it the same way you normally do. The printed path is the interpreter actually in use — compare it against py -m pip --version, which names the Python your pip serves.
Why does the module work in the terminal but not in VS Code?
VS Code selects its own interpreter, shown in the status bar, independently of your terminal. Use "Python: Select Interpreter" from the command palette to point it at the Python you installed the package into.
What is the difference between pip install pillow and import PIL?
Some packages register one name on PyPI and expose another for import — Pillow installs as pillow but is imported as PIL, beautifulsoup4 as bs4, opencv-python as cv2. The package's own documentation states the import name.
Why does import work but the module has no attributes?
A file in your project probably shares the library's name — your requests.py is imported instead of the real package. Print module.__file__: if the path is inside your project, rename your file and delete the __pycache__ folder beside it.
Do I need to reinstall packages for every virtual environment?
Yes — that isolation is the entire point of a venv. Each environment has its own packages, so activate the environment first and install inside it. A requirements.txt makes re-creating the set a single command.
Conclusion
ModuleNotFoundError is almost never about the package and almost always about which Python. Two habits make it rare: install with py -m pip so installer and runner can never diverge, and when it strikes anyway, let sys.executable tell you the truth instead of guessing.
Related: installing Python on Windows for the launcher and PATH fundamentals, and Python projects for beginners once the imports behave.
Comments