Blog / Coding tips

ModuleNotFoundError: No module named in Python: 10 Causes and Fixes (pip, venv, VS Code)

Cover image for ModuleNotFoundError: No module named in Python: 10 Causes and Fixes (pip, venv, VS Code)

ModuleNotFoundError: No module named 'x' means the Python interpreter running your code can’t find a module called x in any of the places it looks. Usually the package isn’t installed in that interpreter: you installed it with a different pip, in a different virtual environment, or under a different name. The fastest fix is to install with the same Python you run, using python -m pip install <package>, and to check the package name, because some differ from their import name (cv2 is opencv-python, bs4 is beautifulsoup4, yaml is PyYAML).

I reproduced each cause below on Linux with Python 3.13 in fresh virtual environments, and pasted the real error messages. The fixes are the same on Windows and macOS; where the commands differ, I show both.

What the error means

When you write import requests, Python searches a list of folders called sys.path: the folder of the script you ran, the standard library, and the site-packages folder of the current interpreter, where pip installs packages. If none of them contains requests, you get:

ModuleNotFoundError: No module named 'requests'

ModuleNotFoundError is a subclass of ImportError, added in Python 3.6, so older guides may call it ImportError: No module named. The fixes are identical.

The key idea for every cause below: each Python installation and each virtual environment has its own site-packages. Installing a package into one doesn’t make it available in another.

Step 1: find out which Python is running your code

Before fixing anything, check which interpreter you’re using:

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

On my test box, the system interpreter printed /usr/bin/python3, and the virtual environment printed ./.venv/bin/python. On Windows you’ll see something like C:\Users\you\AppData\Local\Programs\Python\Python313\python.exe or .venv\Scripts\python.exe.

Then check whether the package is installed for that interpreter:

python -m pip show requests

If it prints a name and version, it’s installed there. If it says “Package(s) not found”, it isn’t.

Cause 1: the package isn’t installed

The simplest case. In a brand-new virtual environment, nothing third-party is installed:

ModuleNotFoundError: No module named 'requests'

Fix: install it with the interpreter you’re using:

python -m pip install requests

On Windows you can also use the launcher: py -m pip install requests. In my test, after installing, import requests worked and printed version 2.34.2.

Cause 2: you installed with a different pip

This is the most common cause of “I installed it but it still says no module named”. Your computer can have several Pythons, and each has its own pip. Typing pip install uses whichever pip is first on your PATH, which may not belong to the python you run.

On my box, which -a pip pip3 listed four different pip paths. Fix: stop using bare pip and always run:

python -m pip install <package>

python -m pip runs the pip that belongs to that exact python, so the package lands where your code will look. This one habit prevents most ModuleNotFoundErrors.

Cause 3: the virtual environment isn’t activated (or is the wrong one)

A virtual environment (venv) is an isolated Python with its own packages. Create and use one like this:

python -m venv .venv
# macOS / Linux
source .venv/bin/activate
# Windows (PowerShell)
.venv\Scripts\Activate.ps1
python -m pip install requests

In my test, the system Python still didn’t have the package after I installed it inside .venv, because they’re separate. If you install inside a venv but run your script with the system Python (or vice versa), you’ll get the error.

Fix: activate the venv before running, or call its Python directly: .venv/bin/python script.py (macOS/Linux) or .venv\Scripts\python script.py (Windows). Add .venv/ to .gitignore; if you already committed it, my guide to removing a file from a Git repo but keeping it locally shows how to untrack it.

Cause 4: the install name is different from the import name

Some packages are installed under one name and imported under another. Trying pip install cv2 fails outright:

ERROR: Could not find a version that satisfies the requirement cv2 (from versions: none)
ERROR: No matching distribution found for cv2

Here are the ones I tested, with the error in a clean venv and the correct install command:

No module named 'cv2'

Install OpenCV: python -m pip install opencv-python (or opencv-python-headless on servers without a display).

No module named 'bs4'

Install Beautiful Soup: python -m pip install beautifulsoup4.

No module named 'yaml'

Install PyYAML: python -m pip install PyYAML.

No module named 'sklearn'

Install scikit-learn: python -m pip install scikit-learn. (The old sklearn package name on PyPI is deprecated; don’t install it.)

No module named 'PIL'

Install Pillow, the maintained fork of PIL: python -m pip install Pillow.

No module named 'dotenv'

Install python-dotenv: python -m pip install python-dotenv.

After installing opencv-python-headless, beautifulsoup4, PyYAML and python-dotenv, all four imports (cv2, bs4, yaml, dotenv) worked in my test venv. If you’re unsure of a name, search the import name on PyPI and check the project’s install instructions.

Cause 5: a typo or wrong capitalisation

Module names are case-sensitive and must be spelled exactly:

ModuleNotFoundError: No module named 'reqeusts'

Check the spelling in the error message carefully; it shows exactly what Python tried to import. import PIL works, import pil doesn’t, on case-sensitive systems.

Cause 6: importing a submodule that doesn’t exist

The error can also mention a dotted name:

ModuleNotFoundError: No module named 'os.paths'; 'os' is not a package

Here the module is os.path, not os.paths. The second half of the message tells you Python found os but couldn’t find the part after the dot. Check the library’s documentation for the correct submodule name.

Cause 7: VS Code is using a different interpreter

VS Code runs your code with whichever interpreter is selected for the workspace, which may not be your venv. If it works in the terminal but not with the Run button, this is almost certainly why.

Fix: open the Command Palette (Ctrl+Shift+P, or Cmd+Shift+P on Mac), run Python: Select Interpreter, and pick the one inside your project’s .venv. The selected interpreter appears in the status bar. Open a new terminal afterwards so it activates the same environment.

Cause 8: Jupyter Notebook uses a different kernel

A notebook runs on a kernel, which is its own Python. Installing a package in your terminal doesn’t help if the kernel is a different interpreter.

Fix: install from inside the notebook with the magic command, which targets the running kernel:

%pip install requests

Then restart the kernel. You can confirm which interpreter the kernel uses by running import sys; print(sys.executable) in a cell.

Cause 9: importing your own files (local modules and packages)

Your own modules are found relative to the folder of the script you run, not the folder you’re in. I tested this layout:

project/
├── run.py                # from app.utils.helpers import hi
└── app/
    ├── main.py           # from utils.helpers import hi
    └── utils/
        ├── helpers.py    # def hi(): return 'hi'
        └── rel.py        # from .helpers import hi

Both python app/main.py and python run.py printed hi, because each import path matches the folder of the script being run. Running python app/utils/rel.py, which uses a relative import, failed with a related error:

ImportError: attempted relative import with no known parent package

Relative imports (from .helpers import hi) only work when the file is run as part of a package. Fix: run it as a module from the project root with -m, using dots instead of slashes and no .py:

python -m app.utils.rel

That printed hi. Running from the project root with -m is the most reliable way to run code inside packages. Note that in modern Python (3.3+) folders work as packages even without an __init__.py file, as my test folders show, but adding one is still common practice.

Cause 10: “error: externally-managed-environment” stops pip installing

On recent Debian, Ubuntu, Fedora and Homebrew Python, installing into the system Python is blocked:

error: externally-managed-environment

× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
    python3-xyz, where xyz is the package you are trying to
    install.

This comes from PEP 668: the operating system manages that Python, and pip would risk breaking system tools. If you ignored this error, the package never installed, so you’d get ModuleNotFoundError afterwards.

Fix: use a virtual environment (Cause 3), which is what the message recommends. For command-line tools, pipx install <tool> installs each tool in its own environment. Avoid --break-system-packages unless you really know what you’re doing.

No module named 'pip'

Sometimes the missing module is pip itself. I created a venv without pip to reproduce it:

$ .venv/bin/python -m pip --version
.venv/bin/python: No module named pip

Fix: Python ships a tool that reinstalls pip:

python -m ensurepip --upgrade

In my test it printed Successfully installed pip-25.1.1, and python -m pip worked again. On Debian and Ubuntu system Pythons, ensurepip may be disabled; install the python3-pip or python3-venv package with apt instead, then create a venv.

No module named 'tkinter' (or '_tkinter')

tkinter, Python’s built-in GUI library, is part of the standard library, yet on my Linux box it was missing:

ModuleNotFoundError: No module named 'tkinter'

That’s because many Linux distributions package it separately. You can’t install it with pip. Fix: on Debian or Ubuntu, sudo apt install python3-tk; on Fedora, sudo dnf install python3-tkinter. On Windows and macOS, the official python.org installers include tkinter; re-run the installer and make sure the “tcl/tk and IDLE” option is ticked.

Python 2 vs Python 3 and the Windows py launcher

On older systems, python may still mean Python 2 while python3 means Python 3. A package installed with pip3 won’t be visible to python, and vice versa. Python 2 reached end of life in 2020, so always use Python 3: run python3 --version to check.

On Windows, the py launcher helps when several versions are installed. py -0 lists them, py -3.13 script.py runs a specific version, and py -3.13 -m pip install requests installs into exactly that version. Using the same py -3.13 for running and installing guarantees they match.

Bonus: a file with the same name as a module

Not strictly ModuleNotFoundError, but closely related. I created a file called random.py next to a script that does import random:

AttributeError: module 'random' has no attribute 'randint' (consider renaming '.../random.py' since it has the same name as the standard library module named 'random' and prevents importing that standard library module)

Python found your random.py first, because the script’s folder comes first in sys.path. Recent Python versions even suggest the fix: rename your file (for example to dice.py) and delete any __pycache__ folder. Common culprits are files named random.py, csv.py, json.py, email.py and requests.py. If you’re working with CSV files, call your script something like read_data.py; my guide to reading a CSV file without pandas uses the standard csv module, which a file named csv.py would hide.

How to check where Python looks for modules

To see the search path, print sys.path:

python -c "import sys; print(sys.path[:2])"

On my box this started with '' (the current folder) and the standard library. To see where an installed package actually lives, use python -m pip show <package> and look at the Location line, or python -c "import requests; print(requests.__file__)".

Keep track of dependencies with requirements.txt

When code moves to a new computer, server or teammate, missing packages are the usual cause of this error. Record what your project needs:

python -m pip freeze > requirements.txt
python -m pip install -r requirements.txt

The second command, run inside a fresh venv on the new machine, installs everything at once. Python 3.15’s new lazy imports also change when a missing module error appears, delaying it to first use; my post on Python lazy imports explains how the traceback shows both places.

ModuleNotFoundError on a server, in CI or in Docker

Code that works on your laptop but fails on a server or in a CI pipeline (such as GitHub Actions) almost always has the same cause: the dependencies weren’t installed in that environment. Check these:

  • Is there a requirements.txt (or pyproject.toml) in the repository? If you forgot to commit it, the server has no list of what to install.
  • Does the build step run python -m pip install -r requirements.txt with the same Python that runs the app? CI images often have several Pythons.
  • In Docker, is the install in the image? The pip install line must run in the Dockerfile before the command that starts your app, and in the same image stage.
  • Is a package only installed locally by hand? If pip freeze on your laptop lists something that isn’t in requirements.txt, the server won’t have it.

A good habit is to test in a brand-new virtual environment before deploying: create it, install only from requirements.txt, and run your tests. If anything is missing, you’ll see the ModuleNotFoundError on your own machine first.

A quick troubleshooting checklist

  1. Read the module name in the error. Is it spelled and capitalised correctly?
  2. Run python -c "import sys; print(sys.executable)" to see which Python runs your code.
  3. Install with that Python: python -m pip install <package>.
  4. Check the install name (cv2 → opencv-python, bs4 → beautifulsoup4, yaml → PyYAML, sklearn → scikit-learn, PIL → Pillow, dotenv → python-dotenv).
  5. Activate your venv, or select it in VS Code and Jupyter.
  6. For your own modules, run from the project root with python -m package.module.
  7. Rename any of your files that clash with a module name.

FAQ

What does ModuleNotFoundError: No module named mean?

It means the Python interpreter running your code can’t find the module you imported in any folder on its search path. Usually the package isn’t installed for that interpreter.

Why do I get “no module named” after pip install?

You probably installed it with a different pip or into a different environment. Run python -m pip install <package> with the same python you use to run your script, and make sure the right virtual environment is active.

How do I fix No module named 'cv2'?

Install OpenCV with python -m pip install opencv-python (or opencv-python-headless on a server). pip install cv2 fails because no package with that name exists.

How do I fix No module named 'bs4' or 'yaml'?

Install beautifulsoup4 for bs4 and PyYAML for yaml, using python -m pip install. The import names are different from the package names.

Why does my code work in the terminal but not in VS Code?

VS Code is using a different interpreter. Run “Python: Select Interpreter” from the Command Palette and choose your project’s virtual environment.

How do I install a package in Jupyter Notebook?

Run %pip install <package> in a notebook cell, then restart the kernel. That installs into the kernel’s own Python.

What does “attempted relative import with no known parent package” mean?

You ran a file that uses a relative import (from .x import y) directly as a script. Run it as a module from the project root instead, for example python -m app.utils.rel.

What is error: externally-managed-environment?

Your operating system manages that Python and blocks pip from installing system-wide (PEP 668). Create a virtual environment with python -m venv .venv, activate it and install there.

// note

How to read this note.

This is a learning note from studying the web. It is one small topic, written so I can remember it. It is not a course and not a claim that I have finished the subject.

If a sentence is wrong, say so from the contact page and name this title. Drafts never appear here. Related notes, when they exist, are other published posts, and the same sample rule applies to each of them.

Python frozendict: The New Immutable Dictionary in Python 3.15 (Tested)
Coding tips

Python frozendict: The New Immutable Dictionary in Python 3.15 (Tested)

Python 3.15 adds frozendict, a built-in immutable, hashable dictionary. Tested examples: creating one, why you can’t change it, using it as a dict key or in a set, merging with |, isinstance checks and a fallback for older Python.

October 12, 2026 · 11 min read · 2 views

Python enumerate(): How to Start at 1 (and 12 Tested Examples)
Coding tips

Python enumerate(): How to Start at 1 (and 12 Tested Examples)

enumerate(items, start=1) gives you a counter that starts at 1 alongside each item. Tested examples for lists, dicts, zip, reversed order, file line numbers and comprehensions, plus why it beats range(len()) and the list.index() trap.

October 11, 2026 · 11 min read · 13 views