Skip to content
Nilay Kabariya

Entry No.083·Fixes·Updated ·3 min read

ModuleNotFoundError: No module named X, but it's installed

pip installed it into one Python and your code runs another: a venv not activated, a Jupyter kernel, a second Python. Five cases reproduced, and the check.

The error, verbatim

Jump to the fix ↓
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'humanize'
✓ Reproduced on Ubuntu 24.04 (GitHub Actions runner)

Tested on

Python
3.13.16 (setup-python) and 3.12.3 (Ubuntu system)
pip
26.2.1 and 24.0
Jupyter
nbconvert + ipykernel in a separate venv
OS
Ubuntu 24.04 (GitHub Actions runner)
Contents
  1. Step 1: compare the two Pythons01
  2. A virtual environment that isn’t active02
  3. Jupyter notebooks03
  4. The package name isn’t the import name04
  5. A file with the same name05
  6. How this was tested06

pip install puts a package into one Python installation. import looks in the Python that’s running your code. If those are two different installations, the package is “installed” and missing at the same time.

That’s the case most of the time. I reproduced it five ways on one machine, with one more look-alike at the end:

What happened Result
pip belonged to Python 3.13, the script ran on the system Python 3.12 No module named 'humanize' on 3.12, fine on 3.13
Installed into a venv, ran without activating it No module named 'httpx'
Installed in a terminal, imported in a Jupyter notebook No module named 'tabulate'
Installed under the import name instead of the package name Could not find a version that satisfies the requirement cv2
A file in the folder had the same name as the package AttributeError, not ModuleNotFoundError

Step 1: compare the two Pythons

Ask both sides where they live:

python -c "import sys; print(sys.executable)"
pip --version

pip --version ends with the Python it belongs to, like (python 3.13), and the path before it shows which installation. If it isn’t the same as sys.executable, they’re two different Pythons.

The fix that always matches is to run pip through the Python you use:

python -m pip install humanize

On Ubuntu and Debian, the system Python refuses plain pip installs with externally-managed-environment. I had to add --user --break-system-packages for that test; a venv is the cleaner way.

On Windows the same split happens between python, py and pip, plus a Microsoft Store placeholder: Python was not found, or pip not recognized covers those.

A virtual environment that isn’t active

I installed httpx with the venv’s own pip, then ran the script with plain python: No module named 'httpx'. The package was in .venv, the script ran outside it.

Activate the venv in that terminal, or call its Python directly:

source .venv/bin/activate      # Windows: .venv\Scripts\activate
python your_script.py

Your editor runs code with its own selected interpreter, so point it at the venv’s Python as well.

Jupyter notebooks

A notebook runs on its kernel, which can be a different Python from your terminal. I ran pip install tabulate in a terminal, then executed a notebook whose kernel lived in another venv: ModuleNotFoundError: No module named 'tabulate'.

Install from inside the notebook with the %pip magic, which always targets the kernel’s Python:

%pip install tabulate

pip may print “Note: you may need to restart the kernel to use updated packages.” In my run the import worked without a restart.

The package name isn’t the import name

Many packages install under one name and import under another. Installing the import name gave these results:

pip install … What happened Install this instead
sklearn failed: “The ‘sklearn’ PyPI package is deprecated, use ‘scikit-learn’” scikit-learn
cv2 Could not find a version that satisfies the requirement cv2 opencv-python-headless (tested) or opencv-python
PIL Could not find a version that satisfies the requirement PIL Pillow
yaml Could not find a version that satisfies the requirement yaml PyYAML
bs4 worked: a stub that pulls in beautifulsoup4 beautifulsoup4
dotenv worked: a stub that pulls in python-dotenv python-dotenv

Install the package name from the last column, then import as before:

python -m pip install scikit-learn

A file with the same name

A script called requests.py next to your code is imported instead of the real package. It doesn’t give ModuleNotFoundError, but it’s the same “it’s installed, why doesn’t it work” feeling. Python 3.13 says so outright:

AttributeError: module 'requests' has no attribute 'get' (consider renaming '.../requests.py' if it has the same name as a library you intended to import)

Rename the file.

How this was tested

Ubuntu 24.04 on a GitHub Actions runner, October 20, 2026, with Python 3.13.16 from setup-python on the PATH and the system Python 3.12.3 at /usr/bin/python3. Packages were installed with each Python’s pip, into a venv run with and without activation, into a terminal versus a Jupyter kernel in its own venv (executed with nbconvert), and under their import names. Every message above is the real output, from the test script.

— N.K., end of entry No.083

Useful? Pass it on:Post on XFollow @EmotionalMatter

Related entries

  1. No.082

    No module named 'pkg_resources': setuptools 82 removed it

    Installing setuptools no longer fixes it: setuptools 82 dropped pkg_resources, and 3.12+ venvs ship without setuptools. Tested with pip, uv and TensorBoard.

    > Traceback (most recent call last):

    FIXED3 min
  2. No.094

    Python CERTIFICATE_VERIFY_FAILED, tested on 3.12 to 3.15

    certificate verify failed: unable to get local issuer certificate, or Basic Constraints of CA cert not marked critical on Python 3.13+. Each cause tested.

    > requests.exceptions.SSLError: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/

    FIXED3 minWindows
  3. No.075

    Python was not found, or pip not recognized (Windows fix)

    "Python was not found" comes from a Microsoft Store placeholder python.exe, not Python, and exits with 9009. How to see which python.exe wins, and the pip fix.

    > Python was not found; run without arguments to install from the Microsoft Store, or disable this shortcut from Settings > Apps > Advanced app settings > App execution aliases.

    FIXED3 minWindows

Post card · Every Sunday

What broke this week.

One email on Sundays: the Node, TypeScript, Python and AI SDK releases that broke builds that week, each one reproduced, with a link to the fix that worked. Never shared, and you can leave any time.

— Nilay

or follow by RSSor on X

By subscribing you agree to the privacy note. One click to leave.

tip: paste the exact error text