You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Vendored scan of a fresh uv checkout (uv.lock, no .venv yet) exits 1 on packages that exist only in the system Python, because the crawler falls back to the global site-packages (the uv side of #947) #964
[agent] Found by the scheduled uv bug-hunt routine (ledger #310).
Summary
This is the uv counterpart of #947 (Pipenv), and the open fix PR for #947 (#950) doesn't cover it. #950 only stops the fallback for Pipenv projects (is_pipenv_project → empty). It keeps crawler_python_e2e.rs::get_site_packages_paths_falls_back_via_uv_lock_marker, which pins the uv.lock → global fallback.
In a uv project checked out fresh (pyproject.toml + uv.lock, before uv sync, so there's no .venv), PythonCrawler::get_site_packages_paths finds no venv. is_python_project(cwd) is then true because of uv.lock / pyproject.toml, so the crawl falls back to get_global_python_site_packages(). Every package in the OS Python joins the candidate set (scannedPackages: 144 for a 2-package lock). scan --mode vendored then tries to vendor the system-only ones into uv.lock and fails:
pkg:pypi/pyyaml@6.0.1 failed pypi_uv_lock_package_missing
"uv.lock has no [[package]] entry for pyyaml; run `uv lock` first"
status: partial_failure, exit 1
The suggested remedy can't help, because pyyaml isn't a project dependency. --dry-run exits 0 with status: success and doesn't flag the refusal.
Impact
CI breakage in the documented vendored flow. A fresh checkout is exactly where vendored mode runs. GitHub ubuntu-* runners and Debian/Ubuntu images ship a system Python with PyYAML, requests, urllib3, jinja2, cryptography, six, idna and more. Whenever Socket has a patch for any of them, every vendored scan of every uv project on that machine exits 1. That includes projects whose own dependencies have no patches at all (repro below: nothing in the lock is patched, and the run still fails).
A system package that shares a name with a lock package masks the lock version. Here the system six 1.16.0 counts as "installed", so lockfileOnlyPackages is 1 instead of 2, and the system copy's bytes stand in for the project's.
Patch counts, the rollout budget (--max-new-patches) and the report include packages that aren't part of the project.
Repro (Linux, Debian/Ubuntu system Python with python3-yaml 6.0.1; a mock public proxy, --proxy-url, offers one free patch for pkg:pypi/pyyaml@6.0.1 and nothing else)
Control: run uv sync first, so .venv exists. The same scan crawls only the venv (scannedPackages: 2, lockfileOnlyPackages: 0), finds no patch, and exits 0. With a mock that also patches six, the run fails the same way for pyyaml while six goes down the normal vendoring path.
Expected vs actual
Expected: CLI_CONTRACT.md, "cwd-only (single project)", says the pypi crawler inspects only the project rooted at --cwd: the manager-recorded env (UV_PROJECT_ENVIRONMENT), $VIRTUAL_ENV, .venv / venv. Global packages are the -g / --global-prefix surface. Lock-only packages already come from uv.lock (lockfileOnlyPackages), so on a fresh checkout the lock is the whole candidate set. The run should vendor what the lock holds, exit 0, and never mention pyyaml.
Actual: system-Python packages join the candidate set. Vendored exits 1 with pypi_uv_lock_package_missing and a misleading uv lock remedy, --dry-run reports success, and system copies mask lock entries.
Cells (main 9c43dfc, CLI 4.0.0, Linux x86_64, system Python 3.11/3.12 dist-packages)
uv (writes uv.lock)
lock revision
vendored, no .venv (×2)
--dry-run
hosted
after uv sync (control)
0.5.31
v1
❌ exit 1, pypi_uv_lock_package_missing (pyyaml)
exit 0, success
144 scanned, pyyaml listed as a project package
—
0.8.17
v1 rev 3
❌ exit 1 (same)
exit 0, success
same
—
0.12.23
v1 rev 5
❌ exit 1 (same)
exit 0, success
same
✅ exit 0, 2 scanned
The behaviour doesn't depend on the uv version: uv only writes the lock, and the crawl is the same for every lock grammar. macOS and Windows weren't probed (the fallback is cross-platform: get_global_python_site_packages also scans Homebrew, python.org and conda roots). Not bisected; the fallback predates vendored uv support.
Suspect code
crates/socket-patch-core/src/crawlers/python_crawler.rs:3047: if is_python_project(&options.cwd).await { return Ok(get_global_python_site_packages().await); } in non-global mode. The doc comment above it ("a fresh clone with pyproject.toml + uv.lock but no .venv would silently return zero packages") predates lock-only discovery. That case is now covered by the lock merge.
crates/socket-patch-core/src/vendor/pypi_uv.rs:330-334: the pypi_uv_lock_package_missing detail recommends uv lock, even when the package isn't a project dependency.
Related: #947 / PR #950 (the Pipenv half; this report came from the Pipenv routine's handover), #504 (agent-mode writes), #476 (Poetry), #502 (PDM).
[agent] Found by the scheduled uv bug-hunt routine (ledger #310).
Summary
This is the uv counterpart of #947 (Pipenv), and the open fix PR for #947 (#950) doesn't cover it. #950 only stops the fallback for Pipenv projects (
is_pipenv_project→ empty). It keepscrawler_python_e2e.rs::get_site_packages_paths_falls_back_via_uv_lock_marker, which pins the uv.lock → global fallback.In a uv project checked out fresh (
pyproject.toml+uv.lock, beforeuv sync, so there's no.venv),PythonCrawler::get_site_packages_pathsfinds no venv.is_python_project(cwd)is then true because ofuv.lock/pyproject.toml, so the crawl falls back toget_global_python_site_packages(). Every package in the OS Python joins the candidate set (scannedPackages: 144for a 2-package lock).scan --mode vendoredthen tries to vendor the system-only ones into uv.lock and fails:The suggested remedy can't help, because pyyaml isn't a project dependency.
--dry-runexits 0 withstatus: successand doesn't flag the refusal.Impact
ubuntu-*runners and Debian/Ubuntu images ship a system Python with PyYAML, requests, urllib3, jinja2, cryptography, six, idna and more. Whenever Socket has a patch for any of them, every vendored scan of every uv project on that machine exits 1. That includes projects whose own dependencies have no patches at all (repro below: nothing in the lock is patched, and the run still fails).six 1.16.0counts as "installed", solockfileOnlyPackagesis 1 instead of 2, and the system copy's bytes stand in for the project's.--max-new-patches) and the report include packages that aren't part of the project.Repro (Linux, Debian/Ubuntu system Python with
python3-yaml6.0.1; a mock public proxy,--proxy-url, offers one free patch forpkg:pypi/pyyaml@6.0.1and nothing else)Control: run
uv syncfirst, so.venvexists. The same scan crawls only the venv (scannedPackages: 2,lockfileOnlyPackages: 0), finds no patch, and exits 0. With a mock that also patches six, the run fails the same way for pyyaml while six goes down the normal vendoring path.Expected vs actual
--cwd: the manager-recorded env (UV_PROJECT_ENVIRONMENT),$VIRTUAL_ENV,.venv/venv. Global packages are the-g/--global-prefixsurface. Lock-only packages already come from uv.lock (lockfileOnlyPackages), so on a fresh checkout the lock is the whole candidate set. The run should vendor what the lock holds, exit 0, and never mention pyyaml.pypi_uv_lock_package_missingand a misleadinguv lockremedy,--dry-runreports success, and system copies mask lock entries.Cells (main
9c43dfc, CLI 4.0.0, Linux x86_64, system Python 3.11/3.12 dist-packages)--dry-runuv sync(control)pypi_uv_lock_package_missing(pyyaml)The behaviour doesn't depend on the uv version: uv only writes the lock, and the crawl is the same for every lock grammar. macOS and Windows weren't probed (the fallback is cross-platform:
get_global_python_site_packagesalso scans Homebrew, python.org and conda roots). Not bisected; the fallback predates vendored uv support.Suspect code
crates/socket-patch-core/src/crawlers/python_crawler.rs:3047:if is_python_project(&options.cwd).await { return Ok(get_global_python_site_packages().await); }in non-global mode. The doc comment above it ("a fresh clone withpyproject.toml+uv.lockbut no.venvwould silently return zero packages") predates lock-only discovery. That case is now covered by the lock merge.crates/socket-patch-core/tests/crawler_python_e2e.rs:1124:get_site_packages_paths_falls_back_via_uv_lock_markerpins the fallback for uv.lock. PR Fix Pipenv project falling back to system Python (#504, #947) #950 leaves it in place.crates/socket-patch-core/src/vendor/pypi_uv.rs:330-334: thepypi_uv_lock_package_missingdetail recommendsuv lock, even when the package isn't a project dependency.Related: #947 / PR #950 (the Pipenv half; this report came from the Pipenv routine's handover), #504 (agent-mode writes), #476 (Poetry), #502 (PDM).