{"record":{"id":"78bc27440fd57ae2","repo":"golang/go","slug":"s-loaded-from-v-but-go-s-would-fail-to-locate-78bc27","errorCode":null,"errorMessage":"%s loaded from %v,\n\tbut go %s would fail to locate it:\n\t%v","messagePattern":"(.+?) loaded from (.+?),\n\tbut go (.+?) would fail to locate it:\n\t(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/modload/load.go","lineNumber":2208,"sourceCode":"\t\t\t// is thus unambiguous in a main module with a pruned module graph) and\n\t\t\t// also one or more transitive dependencies (and is ambiguous with an\n\t\t\t// unpruned graph).\n\t\t\t//\n\t\t\t// It could also occur because some transitive dependency upgrades the\n\t\t\t// module that previously provided the package to a version that no\n\t\t\t// longer does, or to a version for which the module source code (but\n\t\t\t// not the go.mod file in isolation) has a checksum error.\n\t\t\tif _, ok := errors.AsType[*ImportMissingError](mismatch.err); ok {\n\t\t\t\tselected := module.Version{\n\t\t\t\t\tPath:    pkg.mod.Path,\n\t\t\t\t\tVersion: mg.Selected(pkg.mod.Path),\n\t\t\t\t}\n\t\t\t\tpld.error(fmt.Errorf(\"%s loaded from %v,\\n\\tbut go %s would fail to locate it in %s\", pkg.stackText(), pkg.mod, compatVersion, selected))\n\t\t\t} else {\n\t\t\t\tif _, ok := errors.AsType[*AmbiguousImportError](mismatch.err); ok {\n\t\t\t\t\t// TODO: Is this check needed?\n\t\t\t\t}\n\t\t\t\tpld.error(fmt.Errorf(\"%s loaded from %v,\\n\\tbut go %s would fail to locate it:\\n\\t%v\", pkg.stackText(), pkg.mod, compatVersion, mismatch.err))\n\t\t\t}\n\n\t\t\tsuggestEFlag = true\n\n\t\t\t// Even if we press ahead with the '-e' flag, the older version will\n\t\t\t// error out in readonly mode if it thinks the go.mod file contains\n\t\t\t// any *explicit* dependency that is not at its selected version,\n\t\t\t// even if that dependency is not relevant to any package being loaded.\n\t\t\t//\n\t\t\t// We check for that condition here. If all of the roots are consistent\n\t\t\t// the '-e' flag suffices, but otherwise we need to suggest an upgrade.\n\t\t\tif !suggestUpgrade {\n\t\t\t\tfor _, m := range pld.requirements.rootModules {\n\t\t\t\t\tif v := mg.Selected(m.Path); v != m.Version {\n\t\t\t\t\t\tsuggestUpgrade = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}","sourceCodeStart":2190,"sourceCodeEnd":2226,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/modload/load.go#L2190-L2226","documentation":"Emitted by 'go mod tidy' during the backward-compatibility check (checkTidyCompatibility). It means a package resolves successfully under the current toolchain, but the Go version named by -compat (default: the previous major release) would fail to locate that package when re-resolving the import graph. The trailing mismatch.err prints the concrete reason (e.g. an ambiguous-import or checksum failure seen by the older graph).","triggerScenarios":"Running 'go mod tidy' on a module with go >= 1.17 where graph pruning hides a transitive dependency that an older unpruned graph would surface, or where a dependency was upgraded past the version that still contained the imported package, or a checksum error exists in source fetched only by the older graph.","commonSituations":"Upgrading a module from Go 1.16 to 1.17+ and running 'go mod tidy'; a transitive dependency's latest version dropped the imported package; a replaced or retracted module resolves differently across toolchain versions; CI pinning -compat to an older Go.","solutions":["Follow the printed suggestion: run 'go mod tidy -go=<compatVersion>' then 'go mod tidy' with your version to upgrade the requirements consistently.","Run 'go mod tidy -e' to keep the build working while leaving the affected packages unresolved for the older toolchain.","If backward compatibility with the older Go is not required, run 'go mod tidy -compat=<yourGoVersion>' (or drop -compat) so the check is skipped.","Inspect go.sum / run 'go mod verify' to rule out a checksum corruption on the module providing the package."],"exampleFix":"// before\n$ go mod tidy\n// error: <pkg> loaded from <mod>,\n// \tbut go 1.20 would fail to locate it: ...\n\n// after (upgrade the older graph's requirements)\n$ go mod tidy -go=1.20 && go mod tidy -go=1.21\n// or, if 1.20 compat is not needed\n$ go mod tidy -compat=1.21","handlingStrategy":"validation","validationCode":"// Before committing, ensure tidy is reproducible at the compat version:\n//   go mod tidy -go=<compat> && go mod tidy\n// In CI, run: go mod tidy -compat=$(go mod edit -json | jq -r .Go.Version | cut -d. -f1,2)\n// and fail the build if it exits non-zero, so the mismatch is caught pre-merge.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pin -compat in CI to the oldest Go you support and run 'go mod tidy' with it.","After adding/changing a dependency, run 'go mod tidy' then 'go build ./...' on both Go versions.","Keep go.mod's go directive at the version whose pruning semantics you actually want."],"tags":["go-modules","go-mod-tidy","graph-pruning","compatibility","toolchain"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}