Repository navigation
Fix cargo home with HOME unset (#1135) - #1779
Conversation
Assisted-by: Claude Code:claude-opus-5-5
When HOME and CARGO_HOME are both unset (env -i, systemd units, stripped CI or container entrypoints), cargo still builds from the account's passwd home, e.g. /root/.cargo. socket-patch looked only at HOME/USERPROFILE, so an agent scan probed no registry, reported the crate as lockfile-only and exited 0 while cargo compiled the unpatched copy. Global cargo scans found nothing, and the [patch] config chain skipped $CARGO_HOME/config.toml. Resolve the cargo home in one place the way cargo does: CARGO_HOME, then HOME/USERPROFILE, then the passwd entry on Unix. The crawler, the cargo config chain and the build-cache cleaner all use it. Fixes #1135 Assisted-by: Claude Code:claude-opus-5-5
The two #1135 regression tests now use one helper to clear HOME, USERPROFILE and CARGO_HOME. docs/ecosystems.md says how the cargo cache is found when CARGO_HOME is unset. Assisted-by: Claude Code:claude-opus-5-5
Review follow-ups for the cargo home fix: - Read only HOME on Unix and only USERPROFILE on Windows, as cargo does, so a stray USERPROFILE on Linux can't redirect the cache. - Use the passwd entry only when HOME is unset. A set but empty or relative HOME still means no home, so we never patch the shared passwd-home cache that cargo isn't using. - Look the passwd entry up once per process, from utils::fs, so cargo no longer depends on the Gradle crawler. - Self-update's cargo-install check uses the same rule. - The test env guard now restores HOME even if a test panics. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Bugbot is paused — your team has an unpaid invoiceBugbot is paused because your team has an unpaid invoice. Pay it from the billing page in the Cursor dashboard and Bugbot resumes automatically. (requestId: 2df4790e-1391-452f-afb5-bd06211571ae) |
Bugbot is paused — your team has an unpaid invoiceBugbot is paused because your team has an unpaid invoice. Pay it from the billing page in the Cursor dashboard and Bugbot resumes automatically. (requestId: 99ed0440-467b-4417-ab1a-541a6e93f3d7) |
|
[agent] CI is green on Generated by Claude Code |
Cargo's home lookup (std::env::home_dir) skips an empty HOME and falls back to the passwd entry, the same as an unset HOME. We treated HOME= as "no home", so a run with an empty HOME still found no cargo cache and reported every crate lockfile-only. A relative HOME is still refused, since cargo uses it as is. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Bugbot is paused — your team has an unpaid invoiceBugbot is paused because your team has an unpaid invoice. Pay it from the billing page in the Cursor dashboard and Bugbot resumes automatically. (requestId: 731d67ec-bb47-4791-8bdb-a07152df6889) |
Bugbot is paused — your team has an unpaid invoiceBugbot is paused because your team has an unpaid invoice. Pay it from the billing page in the Cursor dashboard and Bugbot resumes automatically. (requestId: 587d318e-f4bd-443b-80b4-0a87cbc37490) |
|
bugbot run Generated by Claude Code |
2 similar comments
|
bugbot run Generated by Claude Code |
|
bugbot run Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 6566a42. Configure here.
|
Ready for review at
Generated by Claude Code |
|
Ready for review at
Generated by Claude Code |
Final review briefWhat it does: Adds one cargo-home resolver, Risk: low. Behaviour only changes when Look here
Verified
Changes I made: none. Open questions (non-blocking nits)
Auto-merge (squash) is armed, so approving sends this PR straight to the merge queue. Generated by Claude Code |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #1135
Summary
With
HOMEandCARGO_HOMEboth unset (env -i, systemd units, strippedCI/container entrypoints), cargo still builds from the account's passwd home
(e.g.
/root/.cargo). socket-patch found no cargo home at all, soscan --mode agentreported the crate lockfile-only and exited 0 while cargocompiled the unpatched copy, and
scan -g -e cargofound no packages. It nowresolves the cargo home the way cargo does and patches the copy cargo builds.
Root cause
Four places resolved the cargo home on their own, each as
$CARGO_HOME, elseutils::fs::home_dir()/.cargo: the cargo crawler, the[patch]config chain(
vendor/cargo_config.rs), the build-cache cleaner(
utils/cargo_build_cache.rs) and the self-update cargo-install check(
update/channel.rs).home_dir()reads onlyHOME/USERPROFILE. Cargo'shomecrate readsHOMEon Unix (USERPROFILEon Windows) and, on Unix,falls back to the passwd entry when
HOMEis unset.Fix
utils::cargo_home::cargo_home():$CARGO_HOMEwhen set and non-blank,else
<home>/.cargo, where<home>isHOME(USERPROFILEon Windows) or,with that variable unset or empty on Unix, the passwd entry (as std's
home_dirdoes). A relativeHOMEstill means no home (unchanged), so we never patch a sharedpasswd-home cache cargo isn't using.
passwd_home()moved fromcrawlers::gradle_cachetoutils::fs(re-exportedfrom
gradle_cache) and is looked up once per process.docs/ecosystems.md(Cargo: shared registry cache) states the rule.Test evidence
cargo test -p socket-patch-core --lib cargo_home_without_home_env_uses_passwd_homefailed before the fix (
CargoCrawler::cargo_home()returnedNone), passes after.utils/cargo_home.rs(CARGO_HOME wins, blank is unset,HOME wins over passwd, unset HOME falls back to passwd (Agent-mode cargo with HOME unset finds no registry cache, reports the crate as lockfile-only and exits 0, while cargo builds the unpatched copy from the passwd home's ~/.cargo #1135), empty HOME falls back to passwd, relative HOME is no home, USERPROFILE ignored on Unix, process-env end to end).
env -u HOME -u CARGO_HOME socket-patch scan -g -e cargo --jsonnow reports
scannedPackages: 238from/root/.cargo(the issue reported 0 on main).cargo fmt --all -- --check: clean.cargo clippy --workspace --all-features -- -D warnings: clean.cargo test -p socket-patch-core --all-features --lib: 6809 passed, 4 failed. The 4(
copy_tree::relax_loop_must_not_traverse_symlinked_root,vlt_heal::an_unremovable_hidden_lock_keeps_every_store_entry,pypi_poetry::wire_write_failure_maps_error_and_leaves_lock_untouched,pypi_requirements::wire_failure_rolls_back_already_written_files) depend onpermission denials and fail only because this container runs as root. They
don't touch this change and pass in CI.
cargo test -p socket-patch-core --all-features --test '*': 655 passed.cargo test -p socket-patch-cli --all-features --bins --lib: 935 passed.e2e_safety_cargo_build -- --ignored10/10,e2e_vendor_cargo_build40/40,e2e_redirect_cargo_build23/23,e2e_redirect_cargo_shapes34/34,mode_migration_cargo30/30.cargo test --workspacebuild ran out of local disk while linking every CLItest binary, so the cargo-related CLI suites above were run one at a time instead.
CI runs the full matrix.
cargo_crawler::tests::cargo_home_without_home_env_uses_passwd_home,utils::cargo_home::tests::*/code-review high
Fixed: Unix read
USERPROFILE(and Windows readHOME), unlike cargo; a relativeHOMEfell through to the passwd home;update/channel.rswas a fifth resolver;the passwd lookup repeated on every call;
utilsdepended on the Gradle crawler;the test env guard wasn't panic-safe.
Not changed:
CARGO_HOMEis still treated as unset. That keeps the existingbehavior and the repo's
env_non_emptyconvention.showing the crawler itself is fixed.
HOME-unset gap are outof scope here. Each tool has its own home rule, so they need separate fixes.
USERPROFILEunset, cargo uses the known-folder API. We don'treplicate that. It is untested in the issue too.
https://claude.ai/code/session_011f9aeNZ3vKbaLRi7eRFxTp
Generated by Claude Code