Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

Go apply writes the shared replace into ./go.work when GOWORK names another file in the same directory, reports success, and the workspace builds unpatched

Geschlossen
#1,810 3 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

@mikolalysenko arbeitet bereits daran.

Seit 29.10.2026.

  • #1812 von @mikolalysenko — offen

Bewertung

Schwierigkeit
4/5
Geschätzter Aufwand
1-2 Tage
Anfängerfreundlichkeit
35/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Veraltet
Tech-Stack
go, rust
Bereich
backend, cli

Rechercherichtung

Read crates/socket-patch-core/src/vendor/go_mod_edit.rs around lines 209 and 273, then trace how ReplaceHost is chosen in vendor/go_workspace.rs and used by go_consumer_sync.rs and patch/redirect/mod.rs. Reproduce with the GOWORK fixture in the issue and check that apply writes to the workspace file Go uses, or refuses without changing files. Confirm apply --check and the member builds reflect the patch; linked PR #1812 is already open.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

agent:claimed agent:triaged bug bughunt pm:go priority:p2

[agent] Found by the scheduled Go modules bug-hunt routine (ledger #317).

Summary

Since #1764 (eb75d20), apply run at a go.work root puts the shared module's replace into go.work. It decides that from the workspace go actually uses (GOWORK), but it always writes the file <root>/go.work. When GOWORK names another file in the same directory (for example GOWORK=$PWD/ci.work next to a developer go.work), the replace lands in a file go doesn't read. apply still reports 1 of 1 targeted patch applied and exits 0, re-runs do the same, and every member builds the unpatched module.

apply --check (exit 1, "missing go.mod replace") and vex (not_applied, exit 1) both catch it, so nothing gets attested. But apply's own success report is wrong, and it changes a file the user didn't ask it to change.

If <root>/go.work doesn't exist at all (only ci.work), apply fails with a misleading failed to update go.mod: read ./go.work: No such file or directory.

v5.0.1 and the parent of eb75d20 (86457da) fail closed on the same fixture: apply exits 1 and writes nothing.

Impact

CI setups that pick a workspace file with GOWORK=/abs/path/x.work (a documented go feature, and docs/ecosystems.md says socket-patch honours it) get a green apply and an unpatched build. The stray replace also changes the developer go.work.

Repro (Linux, go 1.24.7, hermetic file GOPROXY, hand-staged .socket/manifest.json and blob as in e2e_golang_workspace_build.rs::write_local_patch)

# ws/ has no go.mod; members ./a and ./b both `require example.com/upstream v1.0.0`
# (lib returns "PRISTINE"; the patch blob makes it return "PATCHED")
cd ws
printf 'go 1.18\n\nuse (\n\t./a\n\t./b\n)\n' > ci.work   # the workspace CI uses
printf 'go 1.18\n\nuse ./a\n' > go.work                  # a developer's go.work
export GOWORK=$PWD/ci.work
socket-patch apply --offline --ecosystems golang
#  Summary: 1 of 1 targeted patch applied ...   exit 0
grep -l replace go.work ci.work a/go.mod b/go.mod
#  go.work                                       <- only the file go isn't reading
(cd a && go run .); (cd b && go run .)
#  A: PRISTINE
#  B: PRISTINE
socket-patch apply --check --ecosystems golang   # exit 1: missing go.mod `replace`
socket-patch apply --offline --ecosystems golang # exit 0 again, still unpatched

Controls: with GOWORK unset, the same go.work replace makes a print PATCHED (which shows go really reads ci.work above). With a root go.mod that is a use member, the mirrored root go.mod replace happens to patch the build, but apply still adds the replace to the unused go.work.

Expected vs actual

  • docs/ecosystems.md, "Go workspaces (go.work)": "The go.work in effect is GOWORK when it names an absolute file … Run in the directory holding go.work, apply, vendor and scan --mode hosted write the replace … into go.work." Expected: the replace goes into the file in effect (ci.work), or apply refuses. Actual: it goes into ./go.work, and apply reports the patch as applied.
  • CLI_CONTRACT: apply exits 0 only when the patches it reports as applied take effect.

OS × version

OS go main ecd4924 v5.0.1 / 86457da
Linux 1.21.13 fail (exit 0, PRISTINE) —
Linux 1.24.7 fail (3 fresh fixtures) refuses (exit 1, nothing written)
Linux 1.26.8 fail —
macOS / Windows — untested (no probe branch this run) —

Untested: vendor and scan --mode hosted (the hosted engine also builds go.work paths itself, see hosted/engine.rs:554), and rollback/remove of a replace sitting in a non-go.work workspace file.

First bad commit

eb75d20 "Write shared Go patch replaces into go.work (#1764)". Its parent 86457da refuses.

Suspect code

  • crates/socket-patch-core/src/vendor/go_mod_edit.rs:209: let host_path = project_root.join(host.file_name()); gives <root>/go.work. The host decision comes from the resolved workspace file (GoWorkspace::rooted_at, vendor/go_workspace.rs:642, which compares only its directory).
  • crates/socket-patch-core/src/vendor/go_workspace.rs:238: ReplaceHost::GoWork => "go.work", also used by go_consumer_sync.rs:416 and patch/redirect/mod.rs:9464.
  • crates/socket-patch-core/src/vendor/go_mod_edit.rs:273: drop_replace_entry hardcodes project_root.join("go.work") too.

The host should carry the resolved work_file path, or rooted_at should require the file to be <root>/go.work.

Vorherrschende Sprache
Rust
Sterne
8
Forks
2
Ø Merge
19 Std. 12 Min.
Gemergte PRs (30 T.)
709

Entwicklungsumgebung

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus SocketDev/socket-patch

Alle Issues in SocketDev/socket-patch

Ähnliche Issues

Weitere Issues zu Rust

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.