GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — uv rollback, remove and vendor --revert leave an empty `[tool.uv.sources]` header behind when the project's sources are written as `[tool.uv.sources.<name>]` sub-tables · Issue #524 · SocketDev/socket-patch

uv rollback, remove and vendor --revert leave an empty [tool.uv.sources] header behind when the project's sources are written as [tool.uv.sources.<name>] sub-tables #524

New issue
Copy link
New issue
Copy link
Closed
#545
Closed
uv rollback, remove and vendor --revert leave an empty [tool.uv.sources] header behind when the project's sources are written as [tool.uv.sources.<name>] sub-tables#524
#545
Copy link
Labels
agent:triagedbugSomething isn't workingSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agentpm:uvuvuvpriority:p1

Description

@mikolalysenko
Mikola Lysenko (mikolalysenko)
opened on Oct 2, 2026
Issue body actions

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

Summary

Some uv projects write their sources only as sub-tables ([tool.uv.sources.idna] with url = … beneath it) and have no [tool.uv.sources] header. On those projects, hosted scan and vendored scan add an explicit [tool.uv.sources] header that holds the new six = { … } entry. rollback, remove and vendor --revert then remove the entry but keep the header and a blank line. So after a full round trip, pyproject.toml isn't byte-identical to the original: two lines ([tool.uv.sources] and an empty line) are left over.

Impact

The impact is low. The table is empty, uv parses it, uv lock --locked still passes, uv.lock is restored byte for byte, and the install is unchanged. But the tree is left dirty after an unwind, and that breaks "rollback and check for a clean git status" CI flows. It also breaks the restore contract. The residue is stable: a second scan → rollback cycle doesn't add more.

Repro (Linux, real uv 0.8.17 and 0.5.31, main 61cfb9b)

cat > pyproject.toml <<'EOF'
[project]
name = "app"
version = "0.1.0"
requires-python = ">=3.9"
dependencies = ["six==1.16.0", "idna==3.7", "certifi==2024.2.2"]

[tool.uv.sources.idna]
url = "https://files.pythonhosted.org/packages/e5/3e/741d8c82801c347547f8a2a06aa57dbb1992be9e948df2ea0eda2c8b79e8/idna-3.7-py3-none-any.whl"
EOF
uv lock && uv sync && cp pyproject.toml pyproject.orig
socket-patch scan --mode hosted --yes $API      # adds "[tool.uv.sources]\nsix = { url = … }\n\n" above the sub-table
uv sync --locked                                 # six is patched; vex says not_affected (redirected)
socket-patch rollback --yes $API                 # exit 0, status success
diff pyproject.orig pyproject.toml
# > [tool.uv.sources]
# >

The same residue appears with socket-patch remove <uuid> after a hosted scan, and with scan --mode vendored followed by vendor --revert. The patch API was a local mock serving a free six 1.16.0 patch (SRI integrity, deterministic wheel), and SOCKET_PYPI_JSON_API pointed at a pass-through to pypi.org.

Spellings that come back byte-identical, checked alongside: [tool.uv] + sources.idna = {…} (dotted key), a root-level tool.uv.sources.idna = {…}, sources = { idna = {…} } (inline table), and no sources at all.

Expected vs actual

  • Expected: CLI_CONTRACT.md, "Hosted unwind coverage" → "What a restore does": "only the hosted entries change and every other byte stays the file's own". The [tool.uv.sources] header is hosted-mode bytes, so it should go when its last hosted entry goes, the same way it already does when hosted mode created the whole table.
  • Actual: the header and a blank line stay. Exit code 0, with no warning.

OS × version

Cell uv 0.5.31 uv 0.8.17
hosted scan → rollback (Linux) ❌ residue ❌ residue
hosted scan → remove (Linux) – ❌ residue
vendored scan → vendor --revert (Linux) – ❌ residue

The rewrite is a pure text and TOML edit on the CLI side, independent of OS or uv release; uv only has to accept the result. Not bisected: v5 is the first release with the upstream restore.

Suspect code

  • crates/socket-patch-core/src/vendor/pypi_uv.rs:498-502: created_sources_table is false whenever tool.uv.sources exists, including when it's only implied by a [tool.uv.sources.<name>] sub-table. So the remove_table_if_empty(…, "[tool.uv.sources]") call at :887-890 never runs, even though toml_edit printed a new explicit header.
  • crates/socket-patch-core/src/patch/redirect/upstream/uv.rs:1111-1128 (restore_metadata): it removes the key, but the sources table isn't empty (it still holds the idna sub-table), and the table stays explicit, so the header is printed. One possible fix is to mark the table implicit again when only sub-tables remain and it wasn't explicit before the scan.

Activity

  1. Mikola Lysenko (mikolalysenko)
    added
    bugSomething isn't workingSomething isn't working
    bughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agent
    pm:uvuvuv
    on Oct 2, 2026
  2. mikolalysenko commented on Oct 2, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 2, 2026
    CollaboratorAuthor
    More actions

    [agent] Triaged as priority:p1 (uv). Confirmed on main 61cfb9b: created_sources_table in crates/socket-patch-core/src/vendor/pypi_uv.rs is computed from whether tool.uv.sources exists at all, and a [tool.uv.sources.<name>] sub-table makes it exist implicitly, so the explicit header hosted/vendored mode adds is never removed on unwind. No open PR or duplicate found.


    Generated by Claude Code

  3. Mikola Lysenko (mikolalysenko)
    added
    agent:triaged
    priority:p1
    on Oct 2, 2026
  4. mikolalysenko commented on Oct 2, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 2, 2026
    CollaboratorAuthor
    More actions

    [agent] Shares root cause with #544: the uv [tool.uv.sources] wiring assumes a standalone, explicit [tool.uv.sources] header with plain name = {…} lines, but toml_edit writes into whatever spelling the project already has (a dotted sources.<pkg> key under [tool.uv], or a header-less parent implied by [tool.uv.sources.<pkg>] sub-tables). The vendored ledger then records a line the file never contains (#544), and the unwind never removes the header the scan made explicit (#524). Will be fixed together.


    Generated by Claude Code

  5. mikolalysenko commented on Oct 2, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 2, 2026
    CollaboratorAuthor
    More actions

    [agent] Claiming this issue (with #544; shared root cause: uv sources wiring ignores the project's existing sources-table spelling). Branch: agent/fix-uv-sources-table-spelling. Claim-ID: 2026-10-02T09:20:46Z-d304db


    Generated by Claude Code

  6. Mikola Lysenko (mikolalysenko)
    added
    agent:claimed
    on Oct 2, 2026
  7. mikolalysenko commented on Oct 2, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 2, 2026
    CollaboratorAuthor
    More actions

    [agent] Draft PR: #545


    Generated by Claude Code

  8. Mikola Lysenko (mikolalysenko)
    added 4 commits that reference this issue on Oct 2, 2026

    Add failing tests for uv sources spellings

    739ed54

    Fix uv sources unwind on non-default spellings

    6c5737c

    Add real-uv e2e for uv sources spellings

    bec2311

    Fix uv sources unwind on dotted/sub-table spellings (#544, #524) (#545)

    2d57555
  9. Mikola Lysenko (mikolalysenko)
    closed this as completedin #545on Oct 2, 2026
  10. Mikola Lysenko (mikolalysenko)
    removed
    agent:claimed
    on Oct 2, 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

    agent:triagedbugSomething isn't workingSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agentpm:uvuvuvpriority:p1

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.