Fix: Python ModuleNotFoundError even after pip install (venv / virtualenv)
Quick Answer
How to fix ModuleNotFoundError in Python when packages are installed but not found inside a virtual environment. Covers venv activation, pip path issues, IDE settings, conda conflicts, and more.
The Error
You install a package with pip install, the install succeeds, and then you try to import it:
import requestsAnd Python throws:
Traceback (most recent call last):
File "app.py", line 1, in <module>
import requests
ModuleNotFoundError: No module named 'requests'You just installed it. You can even see it in pip list. But Python refuses to find it.
This almost always happens because the Python interpreter running your script is not the same one that pip installed the package into. Virtual environments are the most common cause, and this guide covers every angle of that problem.
If you are getting ModuleNotFoundError outside of virtual environments, see the general guide: Fix: ModuleNotFoundError: No module named in Python.
Why This Happens
Virtual environments work by creating an isolated Python installation inside a directory (usually called venv, .venv, or env). When you activate a virtual environment, your shell updates the PATH so that python and pip point to the copies inside the environment instead of the system-wide ones.
The problem shows up when there is a mismatch between where packages get installed and which Python runs your code. The most common scenarios:
- You forgot to activate the venv. You installed the package into the venv, but you are running the script with system Python.
- You activated the venv but used the wrong
pip. On some systemspipstill points to the system Python even inside an active venv. - Your IDE is using a different interpreter than the one in your terminal.
- The venv is corrupted after a Python version upgrade or system update.
- You have both conda and venv and they are stepping on each other.
Every fix below targets one of these root causes.
Fix 1: Activate the Virtual Environment
The most common cause. You created a venv, installed packages into it, but you are running your script without activating it first.
Linux / macOS (bash/zsh):
source venv/bin/activateWindows (Command Prompt):
venv\Scripts\activate.batWindows (PowerShell):
venv\Scripts\Activate.ps1Fish shell:
source venv/bin/activate.fishAfter activation, your prompt changes (usually showing (venv) at the beginning). Now run your script again.
If you get a PowerShell execution policy error on Windows, run this first:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUserNote: Activation only affects the current terminal session. If you open a new terminal tab, you need to activate again. If you run your script from a cron job, systemd service, or CI pipeline, there is no shell to “activate” in — you need to call the venv’s Python directly:
/path/to/venv/bin/python app.pyOn Windows:
C:\path\to\venv\Scripts\python.exe app.pyThis is more reliable than activation because it removes any ambiguity about which interpreter runs.
Fix 2: Verify You Are Using the Right Python and pip
Even with the venv activated, you might still be calling the wrong binary. Check both:
which python
which pipOn Windows, use where instead of which:
where python
where pipBoth should point to paths inside your virtual environment directory. For example:
/home/user/project/venv/bin/python
/home/user/project/venv/bin/pipIf they point to /usr/bin/python3 or /usr/local/bin/pip3 or a conda path, the venv is not active or something is overriding it.
You can also verify from inside Python itself:
import sys
print(sys.executable)
print(sys.prefix)sys.executable shows which Python binary is running. sys.prefix shows the environment it belongs to. If sys.prefix does not point to your venv directory, you are not running inside the venv.
Pro Tip: Add these two print statements at the top of your script temporarily whenever you hit a
ModuleNotFoundError. It immediately tells you whether you have an interpreter mismatch, saving you minutes of guessing.
Fix 3: Install in the Correct venv with python -m pip
On many systems, especially Linux and macOS, pip and pip3 can point to different Python installations than python and python3. The safest way to install a package is:
python -m pip install requestsThis guarantees that pip runs under the exact same Python interpreter that python resolves to. If your venv is active, python resolves to the venv’s Python, so the package lands in the right place.
Compare these and you may see the difference:
pip --version
python -m pip --versionIf the paths differ, use python -m pip from now on. This avoids an entire class of problems where pip is a leftover symlink to a system Python.
You might also hit issues if your venv was created with python3 but you are calling pip (which might map to Python 2 on older systems). Always match them:
python3 -m venv venv
source venv/bin/activate
python -m pip install requestsIf you are seeing errors about externally managed environments when trying to install with pip, that is a separate issue — your system Python is blocking global installs, which is another reason to use virtual environments in the first place.
Fix 4: Recreate a Corrupted Virtual Environment
Virtual environments can break when:
- You upgrade or reinstall your system Python (e.g., from 3.11 to 3.12).
- You move the project directory to a different path.
- You delete or rename the Python installation the venv was based on.
When this happens, the symlinks inside the venv point to a Python binary that no longer exists or has changed. Packages appear installed (pip list works) but imports fail because the internal paths are stale.
The fix is to recreate the venv. First, save your dependencies:
pip freeze > requirements.txtThen delete and recreate:
rm -rf venv
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txtOn Windows:
rmdir /s /q venv
python -m venv venv
venv\Scripts\activate.bat
pip install -r requirements.txtIf you use a pyproject.toml or Pipfile instead of requirements.txt, use the corresponding install command (pip install ., pipenv install, etc.).
Note: Never move a virtual environment directory to a different location. Venvs contain absolute paths internally, so moving them breaks those paths. Always recreate instead.
Fix 5: Fix PATH Issues (Wrong Python Version Resolving)
Sometimes your PATH has multiple Python versions and the wrong one takes priority. This is common on systems with both system Python and a Homebrew, pyenv, or Windows Store installation.
Check what is on your PATH:
echo $PATHLook for multiple Python directories. On macOS with Homebrew, you might see both /usr/bin/python3 (Apple’s system Python) and /opt/homebrew/bin/python3 (Homebrew Python). The one that appears first in PATH wins.
If you use pyenv, make sure the shims are set up correctly:
pyenv which python
pyenv versionAnd ensure your shell initialization loads pyenv:
# In ~/.bashrc or ~/.zshrc
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"When creating a venv, be explicit about which Python to use:
/usr/bin/python3.12 -m venv venvOr with pyenv:
pyenv shell 3.12.0
python -m venv venvThis avoids the situation where you create the venv with one Python version but your shell later resolves python to a different one. For more on Python path resolution problems, see Fix: python: command not found.
Fix 6: Fix IDE Interpreter Settings (VS Code, PyCharm)
Your terminal might be configured correctly, but your IDE runs code with a different Python interpreter. This is one of the most frustrating scenarios because everything works in the terminal but fails when you click “Run” in your editor.
VS Code
- Open the Command Palette (
Ctrl+Shift+P/Cmd+Shift+P). - Type Python: Select Interpreter.
- Pick the interpreter inside your venv (it will show the venv path).
If your venv does not appear in the list, click Enter interpreter path and browse to:
- Linux/macOS:
venv/bin/python - Windows:
venv\Scripts\python.exe
VS Code stores this in .vscode/settings.json:
{
"python.defaultInterpreterPath": "${workspaceFolder}/venv/bin/python"
}Also check that the integrated terminal activates the venv. VS Code should do this automatically when a venv is detected, but if it does not, add to your settings:
{
"python.terminal.activateEnvironment": true
}PyCharm
- Go to File > Settings > Project > Python Interpreter (or PyCharm > Preferences on macOS).
- Click the gear icon and select Add.
- Choose Existing environment and browse to the
pythonbinary inside your venv. - Click OK and apply.
PyCharm often auto-detects virtual environments, but if you created the venv from the terminal after opening the project, PyCharm may not pick it up until you manually point it to the right interpreter.
Common Mistake: You select the correct interpreter in your IDE, but you also have a launch configuration (like
launch.jsonin VS Code) that overrides the Python path. Check your launch/run configuration for hardcoded interpreter paths.
Fix 7: Fix System Python vs venv Python Confusion
This is a subtle variation of the issues above. You run pip install and it installs the package into system Python while your script runs inside a venv (or vice versa).
This typically happens when:
- You open a terminal, forget to activate, run
pip install some-package(installs globally), then activate the venv and run your script (which looks for the package in the venv). - You use
sudo pip install, which forces a system-wide install regardless of venv activation.
Never use sudo with pip inside a virtual environment. If pip asks for elevated permissions, something is wrong — you are probably not inside the venv.
To verify where a package is installed, run:
python -m pip show requestsCheck the Location field in the output:
Name: requests
Version: 2.31.0
Location: /home/user/project/venv/lib/python3.12/site-packagesIf that path is outside your venv (e.g., /usr/lib/python3/dist-packages), the package was installed globally. Activate your venv and install it again:
source venv/bin/activate
python -m pip install requestsIf you were previously using pip install with the --user flag or encountering distribution errors, those packages land in your home directory’s site-packages, not in any venv. You need to install them again inside each virtual environment that needs them.
Fix 8: Fix Conda vs venv Conflicts
If you use Anaconda or Miniconda alongside standard venv environments, you can end up in a situation where conda’s base environment overrides your venv.
Symptoms:
which pythonshows a conda path even though you activated a venv.conda deactivatechanges your Python to something unexpected.- Packages installed with
conda installare not visible inside your venv (and vice versa).
Rule of thumb: do not mix conda and venv. Use one or the other for a given project.
If you want to use venv but conda keeps interfering, deactivate conda first:
conda deactivateIf conda auto-activates its base environment every time you open a terminal, disable that:
conda config --set auto_activate_base falseThen open a new terminal and create your venv normally:
python3 -m venv venv
source venv/bin/activateIf you want to use conda for the project instead, create a conda environment:
conda create -n myproject python=3.12
conda activate myproject
conda install requestsInside a conda environment, use conda install or pip install (both install into the conda env). But do not create a venv inside a conda environment — the nested environments will cause path confusion and exactly the kind of ModuleNotFoundError you are trying to fix.
If you have already tangled the two, the cleanest fix is to delete both environments and start fresh with one approach. Save your dependencies first:
pip freeze > requirements.txtThen remove the venv, deactivate conda, and pick your path.
Still Not Working?
If you have verified the venv is active, the interpreter is correct, and the package is installed in the right location, here are less common causes to investigate.
Check sys.path
Python searches for modules in the directories listed in sys.path. Print it to see what is happening:
import sys
for p in sys.path:
print(p)Your venv’s site-packages directory should appear in this list. If it does not, something is overriding sys.path. Check for:
- A
PYTHONPATHenvironment variable that points somewhere unexpected (echo $PYTHONPATH). - A
.pthfile orsitecustomize.pythat modifies the path. - A
sys.pathmanipulation at the top of your script or in an__init__.py.
Namespace Packages
If you are working with namespace packages (packages split across multiple directories), an __init__.py file in the wrong place can prevent Python from finding submodules. Check that you do not have an __init__.py at a level that shadows a namespace package.
This also applies when you have a local file or directory with the same name as the package you are importing. For example, if you have a file called requests.py in your project directory, Python imports that instead of the installed requests library. Rename your file.
Editable Installs
If you installed your own package in editable mode (pip install -e .), the package’s source directory must still exist at the original path. If you moved or deleted it, the editable link breaks and you get ModuleNotFoundError.
Reinstall it:
pip install -e .Or install it normally if you do not need live editing:
pip install .Also make sure your pyproject.toml or setup.py correctly lists the package directory. A missing packages or package_dir configuration can cause the install to succeed but the import to fail.
Circular Import Issues
In rare cases, what looks like a ModuleNotFoundError is actually caused by a circular import. Python starts loading module A, which imports module B, which imports module A before A has finished loading. The partially-loaded module may not have the attribute or submodule you expect, causing a confusing error.
If the error only appears for your own modules (not third-party packages), check for circular dependencies between your files.
Verify the Package Name
Some packages have different names for pip install and import. For example:
| pip install | import |
|---|---|
Pillow | from PIL import Image |
python-dateutil | import dateutil |
scikit-learn | import sklearn |
opencv-python | import cv2 |
beautifulsoup4 | from bs4 import BeautifulSoup |
python-dotenv | import dotenv |
If you installed the package but the import name is different, you will get ModuleNotFoundError even though the package is correctly installed. Check the package’s PyPI page or documentation for the correct import name.
Inspect the Package Installation
As a last resort, verify the package files actually exist in your venv:
python -m pip show requestsLook at the Location field, then check that the directory contains the expected package files:
ls $(python -m pip show requests | grep Location | cut -d' ' -f2)/requests/If the directory is empty or missing, the installation is corrupted. Uninstall and reinstall:
python -m pip uninstall requests
python -m pip install requestsVirtual environments are meant to make dependency management easier, but they add a layer of indirection that causes confusion when things go wrong. The key insight is always the same: the Python that runs your code must be the same Python that pip installed the package into. Every fix above comes back to that principle.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: AWS Lambda Unable to import module / Runtime.ImportModuleError
How to fix the AWS Lambda Runtime.ImportModuleError and Unable to import module error caused by wrong handler paths, missing dependencies, layer issues, and packaging problems.
Fix: Python TypeError: unhashable type: 'list'
Learn why Python raises TypeError unhashable type list, dict, or set and how to fix it when using dictionary keys, sets, groupby, dataclasses, and custom classes.
Fix: Django Forbidden (403) CSRF verification failed
How to fix Django 403 CSRF verification failed error caused by missing CSRF tokens, AJAX requests, cross-origin issues, HTTPS misconfig, and session problems.
Fix: FastAPI 422 Unprocessable Entity (validation error)
How to fix FastAPI 422 Unprocessable Entity error caused by wrong request body format, missing fields, type mismatches, query parameter errors, and Pydantic validation.