Repository navigation
The #1282 source-pin guard misses Poetry 1.3 locks (no version in the @generated stamp), so hosted and vendored still rewrite a source = "pypi" dependency and poetry install 1.3 fails with a solver error #1447
Description
[agent] Found by the scheduled Poetry bug-hunt routine (ledger #311).
Summary
#1413 (fix for #1282) refuses to rewrite a Poetry lock for a dependency the pyproject pins with source = "pypi", but only when the lock's @generated by Poetry X.Y stamp names 1.4 – 2.2. Poetry 1.3.x writes the stamp without a version (# This file is automatically @generated by Poetry and should not be changed by hand.), so generated_by_version() returns None and the guard never fires.
Poetry 1.3 has the same installer problem as 1.4. After a hosted or vendored rewrite, poetry install on 1.3.0, 1.3.1 and 1.3.2 fails:
Because demo depends on six (1.16.0) which doesn't match any versions, version solving failed.
Both scans exit 0 with status: success. The only signal is the redirect_poetry_source_constraint / pypi_poetry_source_constraint advisory, and that advisory says the opposite: "Poetry 1.4 – 2.2 refuse to install poetry.lock with that constraint (1.1 – 1.3 and 2.3+ install it)". The docs make the same claim.
Impact
On a Poetry 1.3 project with six = {version = "...", source = "pypi"}, socket-patch scan --mode hosted|vendored commits a lock that no poetry install can consume, on a fresh checkout or in CI. The warning tells the user their Poetry version is fine, so they won't connect it to the patch. This is exactly the #1282 failure, on the one 1.x minor the fix's version window leaves out.
Repro (Linux, Python 3.11, Poetry 1.3.2)
Patch data comes from a local mock of the patch API serving a patched six-1.16.0 wheel (same routes as crates/socket-patch-cli/tests/e2e_vex_build/poetry.rs).
mkdir proj && cd proj
cat > pyproject.toml <<'EOF'
[tool.poetry]
name = "demo"
version = "0.1.0"
description = ""
authors = ["x <x@x.x>"]
[tool.poetry.dependencies]
python = ">=3.8"
six = {version = "1.16.0", source = "pypi"}
EOF
poetry lock # Poetry 1.3.2: stamp has no version, lock-version = "2.0"
head -1 poetry.lock # # This file is automatically @generated by Poetry and should not be changed by hand.
socket-patch scan --mode hosted --yes --json $API # exit 0, status success, applied; warning redirect_poetry_source_constraint ("1.1 – 1.3 ... install it")
mkdir ../fresh && cp pyproject.toml poetry.lock ../fresh && cd ../fresh
POETRY_VIRTUALENVS_IN_PROJECT=true poetry install --no-root
# Because demo depends on six (1.16.0) which doesn't match any versions, version solving failed. (exit 1)scan --mode vendored (copying .socket/ too) gives the same result: exit 0, lock rewired to type = "file", pypi_poetry_source_constraint advisory, then the same solver failure on install.
Expected vs actual
- Expected: what docs/testing/poetry-compatibility.md (lines 38–48) and CLI_CONTRACT.md describe for the 1.4 – 2.2 window: refuse the package before any write (
redirect_poetry_lock_unsupportedhosted,pypi_poetry_source_constraintvendored) when the lock's writer can't install the result. A 1.3 lock can be recognized without a version in the stamp: it's the only writer that emits the@generated by Poetryheader with no version andlock-version = "2.0"(1.2 writes no header andlock-version = "1.1"; 1.4+ put the version in the stamp). - Actual: the rewrite goes through, the scan exits 0, and the advisory says 1.3 installs it.
OS × version (Linux, main 74a44b8)
| Poetry (writer = installer) | Stamp | Hosted | Vendored |
|---|---|---|---|
| 1.2.2 | none (lock-version = "1.1") |
pass (installs patched) | pass |
| 1.3.0 | no version | fail (rewritten, install solver failure) | fail |
| 1.3.1 | no version | fail | fail |
| 1.3.2 | no version | fail (2/2 runs) | fail (2/2 runs) |
1.3.2, no source key (control) |
no version | pass | pass |
| 1.5.1, 1.8.5, 2.2.1 | versioned | pass (refused, lock untouched) | pass (refused) |
| 2.5.1 | versioned | pass (rewritten + warning, installs patched) | pass |
source = "PyPI" (capitalized) behaves the same as "pypi" on 1.5.1 / 2.2.1 / 2.5.1. I didn't run macOS or Windows (probe branches are blocked for this routine). The logic is a text check on the lock header, with nothing OS-specific.
First bad commit
Not bisected. The version window was introduced by #1413 (efd8788), which fixed the 1.4 – 2.2 range measured in #1282. #1282 measured 1.1, 1.2 and 2.3+, but not 1.3, and the CI e2e matrix that runs the new test (ci.yml lines ~1898–1902: 1.0.10, 1.1.15, 1.8.5, 2.0.1, 2.4.3) has no 1.3 leg. poetry-compatibility.yml does list 1.3.2.
Suspect code
crates/socket-patch-core/src/utils/poetry_lock.rs:353source_constraint_breaks_writer:matches!(generated_by_version(lock_text), Some(v) if ((1, 4)..(2, 3)).contains(&v)). A versionless 1.3 stamp isNone, so the guard returns false.crates/socket-patch-core/src/utils/poetry_lock.rs:181generated_by_version: returnsNonefor the 1.3 header.crates/socket-patch-core/src/utils/poetry_lock.rs:342/:350anddocs/testing/poetry-compatibility.md:43: the advisory and docs say "1.1 – 1.3 … install it".
Activity
poetry: run 18 ledger (#1447 filed; #1282/#1023/#671 verified)
mikolalysenko commentedon Oct 12, 2026
[agent] Triaged:
priority:p1(Poetry / PyPI family). Confirmed onmain(6ad6add):generated_by_version(utils/poetry_lock.rs:181) splits the first line on@generated by Poetryand parses the next word, which on a 1.3 header isand, so it returnsNoneandsource_constraint_breaks_writer(:353) returns false. The advisory text at:342also names 1.3 as an installing release. Not a duplicate: #1282/#1413 measured and fixed 1.4 – 2.2 only. No open PR covers it, and it does not share a root cause with the other open Poetry/PyPI issues (#1450 is the Pipenv stale-install remedy).Generated by Claude Code
mikolalysenko commentedon Oct 12, 2026
[agent] Claiming this issue (shared root cause: the Poetry source-pin guard keys on the version in the
@generatedstamp, which Poetry 1.3 omits). Branch: agent/fix-poetry-13-source-pin-guard. Claim-ID: 2026-10-12T21:21:07Z-816258Generated by Claude Code
mikolalysenko commentedon Oct 12, 2026
[agent] Draft PR: #1451
Generated by Claude Code
Refuse source-pinned Poetry 1.3 locks too
CI: run the Poetry e2e on Poetry 1.3.2
Judge an unstamped lock 2.0 as Poetry 1.3 too
mikolalysenko commentedon Oct 12, 2026
[agent] #1451 is ready for review. CI is green on
e161737and Bugbot found no issues. It refuses asource = "pypi"-pinned package over a Poetry 1.3 lock in hosted, vendored and takeover mode. It was verified on real Poetry 1.3.2: the e2e fails on the old guard and passes with the fix. It also adds a 1.3.2 leg to the full-tier Poetry e2e matrix.Generated by Claude Code
chore(release): 5.0.1 (#1485)