python-poetry / python-poetry/poetry

`VIRTUAL_ENV` env var prevents `poetry -C` from finding the target project's in-project `.venv`

Open
#10,773 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

kind/bug status/triage
Dominant language
Python
Stars
34.3k
Forks
2.5k
Avg merge
2d 19h
Merged PRs (30d)
30

Description

Description

When VIRTUAL_ENV is set in the environment, poetry -C <dir> ignores the target project's in-project .venv and uses whatever VIRTUAL_ENV points to instead. This causes Poetry to use the wrong Python version and potentially install into the wrong environment.

This is particularly problematic for:

  • AI coding assistants (e.g. Claude Code) that run Poetry commands in a subprocess where VIRTUAL_ENV may be set to an unrelated path (e.g. /usr)
  • Pre-commit hooks that run poetry -C <dir> install
  • CI environments where VIRTUAL_ENV may be inherited from the runner
  • Monorepos where you activate one project's venv but use -C to operate on another

In the case of Claude Code (Anthropic's AI coding CLI), the subprocess environment has VIRTUAL_ENV=/usr set, which causes all poetry -C commands to use system Python 3.14 instead of the project's .venv with Python 3.13 — breaking installs when the project constrains python < 3.14.

Reproduction
# Works — finds in-project .venv with Python 3.13
$ poetry -C project_a env info
Virtualenv Python: 3.13.12, Path: .venv

# Broken — VIRTUAL_ENV overrides .venv discovery
$ VIRTUAL_ENV=/usr poetry -C project_a env info
Virtualenv Python: 3.14.3, Path: /usr

# Real-world: Claude Code's subprocess environment
$ VIRTUAL_ENV=/usr poetry -C project_a install
# → "Current Python version (3.14.3) is not allowed by the project"
Root cause

In poetry/utils/env/env_manager.py, the get() method:

env_prefix = os.environ.get("VIRTUAL_ENV", os.environ.get("CONDA_PREFIX"))
in_venv = env_prefix is not None and conda_env_name != "base"

if not in_venv or env is not None:
    # In-project .venv discovery happens HERE — but is skipped when VIRTUAL_ENV is set
    if self.in_project_venv_exists():
        venv = self.in_project_venv
        return VirtualEnv(venv)

# Falls through to blindly trust VIRTUAL_ENV:
if env_prefix is not None:
    prefix = Path(env_prefix)
return VirtualEnv(prefix, base_prefix)

When VIRTUAL_ENV is set, in_venv = True, so the condition not in_venv or env is not None is False. The in-project .venv check is entirely skipped and Poetry blindly uses Path(VIRTUAL_ENV).

Suggested fix

When -C/--directory is explicitly used, Poetry should prioritize the target project's in-project .venv over the VIRTUAL_ENV environment variable. The VIRTUAL_ENV from the calling environment is not relevant to the target project.

Workarounds
  1. Unset VIRTUAL_ENV before running Poetry:
    unset VIRTUAL_ENV && poetry -C project_a install
    
  2. cd into the project directory instead of using -C:
    cd project_a && poetry install
    
Poetry Installation Method

install.python-poetry.org

Operating System

Fedora 43

Poetry Version

2.3.2

Poetry Configuration
cache-dir = "/home/reinier/.cache/pypoetry"
data-dir = "/home/reinier/.local/share/pypoetry"
installer.max-workers = null
installer.no-binary = null
installer.only-binary = null
installer.parallel = true
installer.re-resolve = false
keyring.enabled = true
python.installation-dir = "{data-dir}/python"  # /home/reinier/.local/share/pypoetry/python
requests.max-retries = 0
solver.lazy-wheel = true
system-git-client = false
virtualenvs.create = true
virtualenvs.in-project = null
virtualenvs.options.always-copy = false
virtualenvs.options.no-pip = false
virtualenvs.options.system-site-packages = false
virtualenvs.path = "{cache-dir}/virtualenvs"  # /home/reinier/.cache/pypoetry/virtualenvs
virtualenvs.prompt = "{project_name}-py{python_version}"
virtualenvs.use-poetry-python = false
Python Sysconfig
sysconfig.log
Platform: "linux-x86_64"
Python version: "3.13"
Current installation scheme: "posix_prefix"

Paths:
  data = "/usr/local"
  include = "/usr/include/python3.13"
  platinclude = "/usr/include/python3.13"
  platlib = "/usr/local/lib64/python3.13/site-packages"
  platstdlib = "/usr/local/lib64/python3.13"
  purelib = "/usr/local/lib/python3.13/site-packages"
  scripts = "/usr/local/bin"
  stdlib = "/usr/lib64/python3.13"
Poetry Runtime Logs
poetry-runtime.log
$ VIRTUAL_ENV=/usr poetry -vvv -C autogpt_platform/backend env info
Loading configuration file /home/reinier/.config/pypoetry/config.toml

Virtualenv
Python:         3.14.3
Implementation: CPython
Path:           /usr
Executable:     /usr/bin/python
Valid:          True

Base
Platform:   linux
OS:         posix
Python:     3.14.3
Path:       /usr
Executable: /usr/bin/python3.14

$ poetry -vvv -C autogpt_platform/backend env info  # without VIRTUAL_ENV — works correctly
Loading configuration file /home/reinier/.config/pypoetry/config.toml

Virtualenv
Python:         3.13.12
Implementation: CPython
Path:           .venv
Executable:     .venv/bin/python
Valid:          True

Base
Platform:   linux
OS:         posix
Python:     3.13.12
Path:       /usr
Executable: /usr/bin/python3.13

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in poetry/utils/env/env_manager.py and inspect the get() method, especially the VIRTUAL_ENV handling and in_project_venv_exists() check. Reproduce the issue with VIRTUAL_ENV=/usr poetry -C project_a env info, then verify that an explicit target project's .venv is selected despite the inherited environment variable.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
cli, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.