Skip to content

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

Closed

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_unsupported hosted, pypi_poetry_source_constraint vendored) 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 Poetry header with no version and lock-version = "2.0" (1.2 writes no header and lock-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:353 source_constraint_breaks_writer: matches!(generated_by_version(lock_text), Some(v) if ((1, 4)..(2, 3)).contains(&v)). A versionless 1.3 stamp is None, so the guard returns false.
  • crates/socket-patch-core/src/utils/poetry_lock.rs:181 generated_by_version: returns None for the 1.3 header.
  • crates/socket-patch-core/src/utils/poetry_lock.rs:342 / :350 and docs/testing/poetry-compatibility.md:43: the advisory and docs say "1.1 – 1.3 … install it".

Related: #1282 (closed by #1413).

Activity

  1. mikolalysenko commented on Oct 12, 2026

    @mikolalysenko
    CollaboratorAuthor

    [agent] Triaged: priority:p1 (Poetry / PyPI family). Confirmed on main (6ad6add): generated_by_version (utils/poetry_lock.rs:181) splits the first line on @generated by Poetry and parses the next word, which on a 1.3 header is and, so it returns None and source_constraint_breaks_writer (:353) returns false. The advisory text at :342 also 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

  2. mikolalysenko commented on Oct 12, 2026

    @mikolalysenko
    CollaboratorAuthor

    [agent] Claiming this issue (shared root cause: the Poetry source-pin guard keys on the version in the @generated stamp, which Poetry 1.3 omits). Branch: agent/fix-poetry-13-source-pin-guard. Claim-ID: 2026-10-12T21:21:07Z-816258


    Generated by Claude Code

  3. mikolalysenko commented on Oct 12, 2026

    @mikolalysenko
    CollaboratorAuthor

    [agent] Draft PR: #1451


    Generated by Claude Code

  4. added 3 commits that reference this issue on Oct 12, 2026
    194f769
    205351d
    e161737
  5. mikolalysenko commented on Oct 12, 2026

    @mikolalysenko
    CollaboratorAuthor

    [agent] #1451 is ready for review. CI is green on e161737 and Bugbot found no issues. It refuses a source = "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

  6. added a commit that references this issue on Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions