ModuleNotFoundError in Python: the module Python cannot find

ModuleNotFoundError reports that Python found no module under the requested name. Almost always a question of environment rather than code.
5 min read
Believemy logo

Definition

You run a script that starts with a plain import, and it stops cold before its first useful line. That is ModuleNotFoundError firing: Python walked through every place it knows how to look for a module, finding neither a file nor a package under that name.

PYTHON
# pip install requests was run right before this
import requests

# ModuleNotFoundError: No module named 'requests'

This error has only had its own name since Python 3.6; before that, it shared a single exception with a related case, ImportError, with no way to tell a missing module from one that exists but fails to load. The distinction matters for recovery code: catching ModuleNotFoundError only catches the pure absence, catching ImportError catches both, since the first inherits from the second.


Where Python actually looks

Saying Python found nothing "anywhere" still says nothing until that word is spelled out: it actually consults a precise list of folders, called sys.path, built when the program starts and always walked in the same order.

RankWhat gets searched
1The folder of the script that was launched
2The paths declared in the PYTHONPATH variable
3The standard library of the running interpreter
4The packages installed for that same interpreter

Two words in that table explain a good half of the cases seen in practice. "Launched", at the first rank, means the folder of the file that was executed, not the folder the terminal happens to sit in: an in-house module that imports perfectly from the project root can become unfindable from a subfolder, the root having left the list.

"Running", at ranks three and four, means the interpreter executing the code at that exact moment, not whichever one was used to install anything. This is the most frequent cause, the one that trips up nearly everyone once: an installation that succeeded, followed by an import that fails anyway.


The four causes, by frequency

The first connects to the "running" interpreter: the package was installed by an interpreter different from the one running the code, for instance a virtual environment forgotten at launch. Two lines settle it.

PYTHON
import sys
print(sys.executable)  # the path of the interpreter running this script

If the printed path does not match the environment where the installation happened, the cause is found: rerun the script with the right interpreter, or reinstall the package into the one actually in use.

Warning

An editor that kept an old interpreter cached reproduces this trap without warning: the install reports success, the import fails right after, and nothing says the two never spoke to the same Python.

The second cause comes down to the name itself: the name of the package installed and the name of the module imported are two independent strings, chosen separately by the authors, with no guarantee they look alike.

What gets installedWhat gets imported
pillowPIL
beautifulsoup4bs4
python-dateutildateutil
scikit-learnsklearn

The third cause comes from a file that, without meaning to, mistakes itself for a library: a random.py sitting next to the script hides the standard module of the same name, since the current folder holds the first rank in the table above. The error then surfaces from an internal import, at a spot in the traceback with no apparent link to the offending file.

Good to know

print(module_name.__file__) prints the exact path of the file loaded under that name: if it points into your own folder rather than the standard library, the name is colliding.

The fourth cause is the launch folder: importing an in-house module assumes starting from the project root, or going through the -m option. From a subfolder, a script loses that root, and every internal import fails at once.


Telling it apart from its neighbours

Three errors look alike at first glance, and yet they point towards opposite fixes.

ErrorWhat it reportsWhere to look
ModuleNotFoundErrorNo module under that nameEnvironment, installation
ImportErrorThe module exists, the name asked after from is not in itPackage version
NameErrorThe name was never definedA forgotten import

That last row is worth pausing on: forgetting the import produces a name error, not an import error, at the moment the variable is read further down. Knowing which of the three shows up says right away whether something needs installing or a line needs adding at the top of the file.


Frequently asked questions

Question

The installation succeeded, why does the import still fail?

Because the installation and the execution did not target the same interpreter, which happens as soon as a virtual environment is involved. Compare the path of sys.executable with the one of the environment used to install: nine times out of ten, the two differ.

Question

Should this error be caught?

Only for a genuinely optional dependency, one the program can do without. A try followed by an except then allows falling back on another solution or printing a clear message. For a required dependency though, let the exception travel up unchanged: it is already more explicit than any workaround written by hand.

Question

My module sits right next to the script, why is it still not found?

Because "next to the current file" and "in the launch folder" name two different things, and it is the second one that matters to Python. Run the program from the project root rather than from a subfolder, or declare that folder as a package, and check that no file name collides with a library already installed.

Related terms

Discover our python glossary

Browse the terms and definitions most commonly used in development with Python.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.