{"record":{"id":"859b6e206fc9b52a","repo":"golang/go","slug":"updates-to-go-mod-needed-but-go-mod-is-part-of-th","errorCode":null,"errorMessage":"updates to go.mod needed, but go.mod is part of the overlay specified with -overlay","messagePattern":"updates to go\\.mod needed, but go\\.mod is part of the overlay specified with -overlay","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/modload/init.go","lineNumber":2055,"sourceCode":"\n\tif !dirty && cfg.CmdName != \"mod tidy\" {\n\t\t// The go.mod file has the same semantic content that it had before\n\t\t// (but not necessarily the same exact bytes).\n\t\t// Don't write go.mod, but write go.sum in case we added or trimmed sums.\n\t\t// 'go mod init' shouldn't write go.sum, since it will be incomplete.\n\t\tif cfg.CmdName != \"mod init\" {\n\t\t\tif err := ld.Fetcher().WriteGoSum(ctx, keepSums(ld, ctx, ld.pkgLoader, ld.requirements, addBuildListZipSums), mustHaveCompleteRequirements(ld)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\n\tmainModule := ld.MainModules.mustGetSingleMainModule(ld)\n\tmodFilePath := modFilePath(ld.MainModules.ModRoot(mainModule))\n\tif fsys.Replaced(modFilePath) {\n\t\tif dirty {\n\t\t\treturn errors.New(\"updates to go.mod needed, but go.mod is part of the overlay specified with -overlay\")\n\t\t}\n\t\treturn nil\n\t}\n\tdefer func() {\n\t\t// At this point we have determined to make the go.mod file on disk equal to new.\n\t\tld.MainModules.SetIndex(mainModule, indexModFile(updatedGoMod, modFile, mainModule, false))\n\n\t\t// Update go.sum after releasing the side lock and refreshing the index.\n\t\t// 'go mod init' shouldn't write go.sum, since it will be incomplete.\n\t\tif cfg.CmdName != \"mod init\" {\n\t\t\tif err == nil {\n\t\t\t\terr = ld.Fetcher().WriteGoSum(ctx, keepSums(ld, ctx, ld.pkgLoader, ld.requirements, addBuildListZipSums), mustHaveCompleteRequirements(ld))\n\t\t\t}\n\t\t}\n\t}()\n\n\t// Make a best-effort attempt to acquire the side lock, only to exclude\n\t// previous versions of the 'go' command from making simultaneous edits.","sourceCodeStart":2037,"sourceCodeEnd":2073,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/modload/init.go#L2037-L2073","documentation":"With `-overlay`, the go command reads go.mod from a substitute file. If the build determines go.mod needs to be rewritten (dirty=true) but go.mod itself is part of the overlay (fsys.Replaced returns true), it refuses to write because it cannot propagate changes back into an overlay-mapped file. The command aborts to avoid a silently stale go.mod.","triggerScenarios":"Any command that mutates go.mod (go get, go mod tidy/edit, build with -mod=mod) run together with `-overlay=<file>` whose JSON maps the module's go.mod path to another file.","commonSituations":"Editor/LSP/gopls or build tools that build a synthetic overlay and accidentally include go.mod; CI that overlays the whole module directory.","solutions":["Remove the go.mod entry from the overlay JSON so the real on-disk file is used.","Run the command without `-overlay` when it needs to update go.mod.","Force read-only mode (-mod=readonly) so no go.mod write is attempted."],"exampleFix":"// before overlay.json\n// {\"Replace\": {\"/mod/go.mod\": \"/tmp/generated-go.mod\"}}\n//   cmd: go get -overlay overlay.json example.com/x@latest\n\n// after overlay.json (go.mod removed)\n// {\"Replace\": {}}\n//   cmd: go get example.com/x@latest","handlingStrategy":"validation","validationCode":"// Ensure go.mod is NOT covered by the -overlay before running a mutating command.\nfunc overlayExcludesGoMod(overlayPath string) error {\n    b, err := os.ReadFile(overlayPath)\n    if err != nil { return err }\n    if bytes.Contains(b, []byte(\"go.mod\")) {\n        return fmt.Errorf(\"overlay includes go.mod; remove it before go get/mod tidy\")\n    }\n    return nil\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Scope overlays to source files only, never go.mod/go.sum.","When writing build tooling, strip go.mod from generated overlays.","Prefer -mod=readonly for read-only overlay-driven checks."],"tags":["overlay","go-mod","build-flags","gopls"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}