Cursor Python Venv Not Detected (Wrong Interpreter)

Cursor picks the system Python instead of your project venv, breaking imports, linting, and agent-generated code. Diagnose the interpreter picker, venv discovery, and shell PATH.

You activated .venv, ran pip install -r requirements.txt, and everything works in your terminal. You open the same project in Cursor and every import lights up red. Pylance reports Import "fastapi" could not be resolved. The Composer suggests pip install fastapi even though it is already installed. The status bar shows Python 3.11.7 64-bit pointing at /usr/local/bin/python3 instead of .venv/bin/python. This is a Python-extension interpreter discovery problem — not a real package install issue — and it cascades into every other surface: linting, type checking, agent edits, and run-and-debug.

Common causes

Ordered by likelihood for venv detection failures.

1. Cursor picked the wrong interpreter on first open

The Python extension scans for interpreters at workspace open and caches the choice in .vscode/settings.json. If the venv was created after that first open — or under a non-standard path — the cached choice points at the system Python and never updates.

How to spot it: .vscode/settings.json has "python.defaultInterpreterPath" pointing at /usr/local/bin/python or /opt/homebrew/bin/python3 rather than .venv/bin/python.

2. Venv lives outside the workspace root

If your venv is at ~/.virtualenvs/myproj (virtualenvwrapper) or in a sibling directory, the extension’s auto-scan misses it. Only ./.venv, ./venv, ./env get auto-detected.

How to spot it: which python in the integrated terminal shows the right venv, but the status-bar interpreter does not list it as an option.

3. Poetry / PDM / Hatch / uv-managed venv

Tools like poetry and uv store venvs in centralized caches (~/.cache/pypoetry/virtualenvs/..., ~/.local/share/uv/python/...). Cursor’s Python extension picks them up only if the relevant plugin is enabled or the path is supplied explicitly.

How to spot it: poetry env info --path returns a path that does not appear in the interpreter picker.

4. Conda environment not activated in Cursor’s launcher

Conda envs need either Anaconda Python extension support enabled or a python.condaPath setting. Without it, the env appears with the wrong base prefix and imports fail.

How to spot it: conda info --envs shows your env, but in Cursor the interpreter list shows it as (base) even when you select the project env.

5. Shell PATH differs between Cursor and terminal

Cursor inherits PATH from the parent process that launched it (Finder, Dock, Spotlight). If you depend on .zshrc/.bashrc for venv activation, those rc files never run for the GUI process.

How to spot it: Open the integrated terminal — echo $PATH is missing the entries you set in .zshrc. A fresh Terminal.app shows them fine.

6. Workspace is multi-root and the active root has no Python config

In a multi-root workspace, each folder can have its own Python interpreter. The status bar reflects whichever folder owns the active editor file — flipping between files in different roots silently swaps interpreter.

How to spot it: Imports work in one file but not in another in the same Cursor window. Status-bar interpreter changes when you click between them.

Before you start

  • Confirm the venv actually works: source .venv/bin/activate && python -c "import fastapi" succeeds from a plain terminal.
  • Note your venv location and tool (raw venv, virtualenv, poetry, pdm, uv, conda).
  • Record the current interpreter shown in the Cursor status bar — bottom right, click “Python”.
  • Capture .vscode/settings.json before edits.

Information to collect

  • Output of which python and python --version from Cursor’s integrated terminal.
  • Output of poetry env info --path or uv venv --path if applicable.
  • Contents of .vscode/settings.json (Python-related keys).
  • Status-bar interpreter path (full path, not just label).
  • Pylance “Show language server output” log — look for Selected interpreter: line.
  • Whether Cursor was launched from Finder, terminal cursor ., or Spotlight.

Step-by-step fix

Ordered fastest to most thorough.

Step 1: Set the interpreter explicitly via the command palette

Cmd+Shift+P -> Python: Select Interpreter -> “Enter interpreter path…” and paste the absolute path:

/Users/you/proj/.venv/bin/python

This writes python.defaultInterpreterPath to .vscode/settings.json and triggers an analyzer restart. 80% of cases stop here.

If you do not see the path you want in the list, click “Enter interpreter path…” -> “Find…” and browse to it.

Step 2: Pin the interpreter in workspace settings

Open .vscode/settings.json and lock it in:

{
  "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
  "python.terminal.activateEnvironment": true,
  "python.analysis.extraPaths": ["${workspaceFolder}/src"]
}

Using ${workspaceFolder} keeps the path portable across machines. Commit this file so teammates inherit the choice.

Step 3: Fix PATH inheritance for GUI launches

If integrated-terminal echo $PATH is missing entries, the rc files are not loading. Two options.

Move PATH-setting lines out of .zshrc (interactive only) into .zprofile (login shells, which Cursor’s terminal uses):

# ~/.zprofile
export PATH="/opt/homebrew/bin:$HOME/.local/bin:$PATH"

Or launch Cursor from a terminal so it inherits the right environment:

cursor .

After either fix, restart Cursor entirely (not just reload window).

Step 4: For Poetry / uv / PDM, point Cursor at the managed venv

Get the path:

poetry env info --path
# or
uv venv --path

Then either select that path via Step 1, or configure the tool to create venvs in-project:

poetry config virtualenvs.in-project true
poetry env remove --all
poetry install

A .venv folder now appears in the workspace root and auto-detection works.

Step 5: For Conda, install the Anaconda Python extension and set conda path

In Cursor extensions, install “Python” (Microsoft) and ensure the Conda integration is enabled. Then:

{
  "python.condaPath": "/opt/homebrew/Caskroom/miniforge/base/condabin/conda",
  "python.defaultInterpreterPath": "/opt/homebrew/Caskroom/miniforge/base/envs/myproj/bin/python"
}

Activate via Cmd+Shift+P -> Python: Select Interpreter and pick the conda env explicitly.

Step 6: For multi-root workspaces, pin per folder

Each folder in a multi-root workspace can carry its own .vscode/settings.json. Add the pin to every Python folder:

{
  "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python"
}

Now switching between files no longer flips interpreters.

Verify

  • Open a .py file from the project. Status bar shows Python 3.x.x (.venv) or your tool’s name.
  • Type import <pkg> for a package only present in the venv. No red squiggle.
  • Run python -c "import sys; print(sys.executable)" in a debug session — output matches .venv/bin/python.
  • Ask Composer to “add a fastapi route” — it should not propose pip install fastapi if it is already in requirements.txt.

Long-term prevention

  • Always create the venv before opening the project in Cursor for the first time.
  • Commit .vscode/settings.json with python.defaultInterpreterPath pinned.
  • Use poetry config virtualenvs.in-project true (or uv venv .venv) so the venv lives at ./.venv and gets auto-detected.
  • Put PATH-setting commands in .zprofile not .zshrc so GUI launches inherit them.
  • Add a make setup / just setup target so new contributors get the venv at the standard path.
  • Run python -c "import sys; print(sys.prefix)" as part of pytest startup; assert it matches .venv in CI.

Common pitfalls

  • Selecting the interpreter once, then deleting and recreating the venv — the cached path now points at a non-existent binary. Re-select after rm -rf .venv && python -m venv .venv.
  • Putting python.defaultInterpreterPath in user settings instead of workspace settings — it leaks across projects.
  • Activating the venv in the integrated terminal and assuming Pylance now sees it. Pylance uses the configured interpreter, not the terminal’s active venv.
  • Trusting the status-bar label alone — it can say .venv but actually point at a stale path. Verify with python -c "import sys; print(sys.executable)".
  • Running cursor . from a terminal where the venv is already activated and getting different behavior than launching from Finder. Standardize one launch method per machine.
  • Forgetting that conda envs need an extra python.condaPath setting beyond just the interpreter pin.

FAQ

Q: Composer keeps suggesting pip install for packages already installed.

The agent reads the interpreter Cursor has selected. Fix the interpreter first; the suggestions will stop. See also Cursor reads wrong file.

Q: I changed python.defaultInterpreterPath but nothing updated.

Pylance caches the analyzer state. Cmd+Shift+P -> Python: Restart Language Server, or just reload the window.

Q: My venv is at ~/.virtualenvs/myproj. Can I keep it there?

Yes — pin the absolute path in .vscode/settings.json. But moving to ./.venv per project is simpler and more portable.

Q: Tests pass in terminal but fail under Cursor’s test explorer.

The test runner uses Cursor’s configured interpreter, not your active terminal venv. Verify the interpreter pin matches what the terminal uses.

Tags: #Cursor #Troubleshooting #Debug #AI coding