-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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_ENVmay be set to an unrelated path (e.g./usr) - Pre-commit hooks that run
poetry -C <dir> install - CI environments where
VIRTUAL_ENVmay be inherited from the runner - Monorepos where you activate one project's venv but use
-Cto 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
- Unset
VIRTUAL_ENVbefore running Poetry:unset VIRTUAL_ENV && poetry -C project_a install
cdinto 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 = falsePython 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