Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

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

クローズ
#1,810 コメント 3 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@mikolalysenko がすでに取り組んでいます。

2026年10月29日 から。

  • #1812 @mikolalysenko による — オープン

評価

難易度
4/5
見積もり時間
1〜2日
初心者へのやさしさ
35/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
停滞
技術スタック
go, rust
領域
backend, cli

調査の方向性

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.

索引モデルが issue の本文から書いたものです。

説明

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.

主要言語
Rust
スター
8
フォーク
2
平均マージ
19時間 12分
マージ済み PR(30日)
709

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

SocketDev/socket-patch のほかの issue

SocketDev/socket-patch の issue をすべて見る

似ている issue

Rust の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。