You run pip install requests. The terminal prints Successfully installed requests-2.32.3. You run your script and get:
ModuleNotFoundError: No module named 'requests'
The package isn't broken and the install didn't fail. In almost every case I've debugged, the package went into one Python and your script is running on another one. A typical machine has several: the system Python, a python.org install, a Microsoft Store Python, maybe Anaconda, plus a virtual environment per project. Each has its own site-packages folder, and a package installed into one is invisible to the others.
So stop reinstalling and ask a better question: which interpreter is running this code, and which interpreter did pip install into?
Step 1: Ask the running Python who it is
Put these two lines at the very top of the failing script, or run them in the same terminal, notebook or editor run button that throws the error:
import sys
print(sys.executable)
Then ask pip where it installed the package:
pip show requests
Look at the Location: line. If sys.executable points to C:\Users\you\project\.venv\Scripts\python.exe and Location: points to C:\Users\you\AppData\Local\Programs\Python\Python312\Lib\site-packages, you've found the bug in thirty seconds. Different interpreters, different packages.
You can also check from the shell which pip and which python your terminal resolves to:
# Windows (CMD or PowerShell)
where python
where pip
# macOS / Linux
which -a python3
which -a pip3
If those lists start with different folders, pip and python don't belong to each other.
Step 2: Install with the interpreter, not with a bare pip
The single habit that prevents most of these errors is to never call pip on its own. Call it through the exact Python you'll run:
python -m pip install requests
python -m pip guarantees pip installs into the site-packages of that python. If you want to be completely explicit, use the path you printed in step 1:
C:\Users\you\project\.venv\Scripts\python.exe -m pip install requests
On Windows, the py launcher can pick a version for you (py -3.12 -m pip install requests), but be aware that py doesn't know about your activated venv unless you call python from inside it. Inside a project, prefer the venv's own python.
If python -m pip itself fails with No module named pip, that interpreter has no pip yet. python -m ensurepip --upgrade usually restores it. I wrote up the other recovery paths, including broken venvs and PATH issues, in how to fix ModuleNotFoundError: No module named pip.
Step 3: Check the five places the mismatch usually hides
1. The venv wasn't active when you installed
Virtual environment activation only lasts for that terminal session. Open a new terminal, forget to activate, run pip install, and the package lands in your global Python. Then you activate the venv, run the script, and it isn't there.
Check for the (.venv) prefix in your prompt before installing anything. On Windows:
.venv\Scripts\activate # CMD
.venv\Scripts\Activate.ps1 # PowerShell
If PowerShell refuses with an execution policy error, Set-ExecutionPolicy -Scope CurrentUser RemoteSigned is the usual fix. My step-by-step venv guide for Windows covers CMD vs PowerShell activation, .venv vs venv naming, and why you shouldn't commit the folder to Git.
2. Your editor picked a different interpreter
VS Code, PyCharm and other editors have their own interpreter setting, separate from your terminal. The terminal can be inside .venv while the Run button uses the global Python.
In VS Code, open the Command Palette, run Python: Select Interpreter, and choose the one inside your project's .venv. The selected interpreter is shown in the status bar. If the error only appears when you click Run but not when you type python script.py, this is your cause.
3. Jupyter is running a different kernel
Notebooks are the worst offender, because the kernel is a separate process. Running !pip install pandas in a cell installs into whatever pip is first on the shell PATH, which may not be the kernel's Python.
Use the magic command instead, which targets the running kernel:
%pip install pandas
Then restart the kernel. import sys; sys.executable inside the notebook tells you which environment the kernel is really using.
4. Multiple Python versions, one pip
Installing Python 3.12 doesn't remove 3.11. If pip belongs to 3.11 and python resolves to 3.12, every install goes to the wrong version. The giveaway is the version number inside the Location: path from pip show.
python -m pip fixes this permanently because the pip always matches the python.
5. Your file is shadowing the package
This one isn't an interpreter problem, but it produces confusing import errors. If your script is called requests.py, random.py or pandas.py, or there's a folder with that name next to it, Python imports your file instead of the installed package. You'll see ModuleNotFoundError: No module named 'requests.adapters', or an AttributeError like module 'requests' has no attribute 'get'.
Rename the file, and delete any __pycache__ folder next to it.
A quick note on package names vs import names
Sometimes the install and the import really are different names. pip install beautifulsoup4 gives you import bs4. pip install opencv-python gives you import cv2. pip install Pillow gives you import PIL. pip install python-dotenv gives you import dotenv. If pip show finds the package in the right interpreter and the import still fails, check the import name in the package's docs.
The 60-second checklist
When pip says it installed and Python says it can't find it:
- Print
sys.executablefrom the place that fails (script, Run button, notebook). - Compare it with the
Location:frompip show <package>. - Reinstall with
<that python> -m pip install <package>. - Make sure the venv is active and your editor or kernel points at it.
- Check that no local file or folder shadows the package name.
That's all it usually takes. ModuleNotFoundError is one of the most common errors beginners hit, and I cover it alongside fourteen others, with real tracebacks, in Common Python errors: 15 fixes with real examples.
I write practical debugging guides for Python, Laravel, Next.js and Node.js at Blogs World, along with free browser-based developer tools like a JSON formatter and a regex tester.
Top comments (0)