Skip to content

Agent-mode scan misses Poetry's venv for nameless non-package-mode projects, [project].name overrides, and in-project = false with a stray .venv, and still exits 0 #327

Description

[agent] Found by the scheduled Poetry bug-hunt routine (ledger #311).

Summary

scan --mode agent finds Poetry's out-of-tree virtualenv by rebuilding Poetry's env name (<name>-<hash>-py<X.Y>) and its in-project decision without running Poetry (find_poetry_virtualenv_site_packages). Three common Poetry configurations don't match Poetry's own choice:

  1. Nameless non-package-mode project (Poetry ≥ 1.8): [tool.poetry] package-mode = false with no name. Poetry names the env non-package-mode-<hash>-py3.X. poetry_project_names returns no names, so discovery returns nothing.
  2. [project].name and [tool.poetry].name both set (Poetry 2.x): Poetry uses [project].name (poetry check: "[project.name] and [tool.poetry.name] are both set. The latter will be ignored."). The crawler prefers [tool.poetry].name, so it looks for the wrong prefix.
  3. virtualenvs.in-project = false set explicitly, with a ./.venv dir present (any Poetry): Poetry honours the explicit false and installs into its cache venv. find_local_venv_site_packages stops at ./.venv (step 2) before it ever consults Poetry's config.

In every case the scan falls back to the wrong interpreter (the global site-packages, or the stray .venv), reports the patch skipped / package_not_installed, and exits 0 with "status": "success". The venv Poetry actually uses stays unpatched.

Impact

Agent mode silently doesn't patch a normally installed Poetry project, and a CI job gating on the exit code passes. Case 1 is the documented Poetry ≥ 1.8 way to manage an application's dependencies without packaging it. Case 2 is common in projects migrating to PEP 621 on Poetry 2. Case 3 shows up when a .venv created by another tool is left behind. The docs say "a bare socket-patch scan --mode agent / rollback in a default-configured Poetry checkout works" (docs/testing/poetry-compatibility.md, "Mode notes").

Repro (Linux, Poetry 2.4.3, default config)

mkdir nameless && cd nameless
cat > pyproject.toml <<'EOF'
[tool.poetry]
package-mode = false

[tool.poetry.dependencies]
python = ">=3.8"
six = "1.16.0"
EOF
poetry install            # -> ~/.cache/pypoetry/virtualenvs/non-package-mode-XXXXXXXX-py3.12
# patch API with one [email protected] patch (wiremock/local mock, same routes as tests/e2e_vex_build/poetry.rs)
SOCKET_API_URL=http://127.0.0.1:18080 SOCKET_API_TOKEN=fake SOCKET_ORG_SLUG=test-org \
  socket-patch scan --mode agent --json --yes; echo "exit=$?"
# -> "status": "success", apply.patches[0] = {"action":"skipped","errorCode":"package_not_installed"}, exit=0
grep -c SOCKET_PATCHED "$(poetry env info -p)"/lib/python3.*/site-packages/six.py   # 0

Case 2: same, with [project] name = "pep-name" … dependencies = ["six==1.16.0"] plus [tool.poetry] name = "legacy-name" (Poetry places the env at pep-name-…).
Case 3: a named project, poetry.toml containing [virtualenvs]\nin-project = false, plus python -m venv .venv before poetry install.

Control: the same project with [tool.poetry] name = "probe-named" gets "action": "added" and the venv file is patched.

Expected vs actual

  • Expected: the crawler resolves the same env as poetry env info -p (docs/testing/poetry-compatibility.md: "reproducing Poetry's own placement from POETRY_*, the project's poetry.toml, the user config.toml and the platform default cache dir"). Failing that, it should not report success while Poetry's venv holds the package unpatched.
  • Actual: wrong interpreter crawled, package_not_installed, exit 0.

OS × Poetry matrix

Measured with the probe workflow (a real poetry install, then socket-patch scan --mode agent, then reading the installed six.py):

Case Linux 1.8.5 Linux 2.0.1 Linux 2.3.3 (local) Linux 2.4.3 macOS 1.8.5 Windows 1.8.5 / 2.0.1 / 2.4.3
named project (control) ✅ patched ✅ ✅ ✅ ✅ ❌ (separate Windows issue)
1. nameless non-package-mode ❌ ❌ ❌ ❌ ❌ ❌
2. [project].name + [tool.poetry].name n/a (1.8 ignores [project]) ❌ ❌ ❌ n/a ❌
3. in-project = false + stray .venv ❌ ❌ ❌ ❌ ❌ ❌

First bad version

Never worked. Released 4.0.0 has no Poetry out-of-tree discovery at all (the named control also fails on 4.0.0). Discovery arrived in ff6aaae (#241, unreleased), which has these gaps.

Suspect code

  • crates/socket-patch-core/src/crawlers/python_crawler.rs:503 poetry_project_names: prefers [tool.poetry].name, and returns no names when neither table has one. poetry-core uses [project].name first, then [tool.poetry].name, then "non-package-mode" when package-mode = false.
  • crates/socket-patch-core/src/crawlers/python_crawler.rs:287 / :297 find_local_venv_site_packages: ./.venv wins unconditionally. Poetry uses .venv only when virtualenvs.in-project is unset or true, not when it's explicitly false.

Probe runs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions