golang/go · error
%s@%s used for two different module paths (%s and %s)
Error message
%s@%s used for two different module paths (%s and %s)
What it means
Thrown by checkMultiplePathsUncached (load.go:2044) when the same module source (resolveReplacement(mod) — which resolves to the module itself or its replacement) is referenced by two different module paths. The map firstPath[src] tracks the first path seen for each source; if a later module shares the source but has a different Path, the conflict is reported. This indicates a module graph where one physical source is ambiguously attributed to two logical modules.
Source
Thrown at src/cmd/go/internal/modload/load.go:2044
// directives, both fixed for the lifetime of mg, so skip it on
// subsequent calls sharing the same graph.
mg.checkPathsOnce.Do(func() {
checkMultiplePathsUncached(ld, pld, mg.BuildList())
})
return
}
}
checkMultiplePathsUncached(ld, pld, pld.requirements.rootModules)
}
func checkMultiplePathsUncached(ld *Loader, pld *packageLoader, mods []module.Version) {
firstPath := map[module.Version]string{}
for _, mod := range mods {
src := resolveReplacement(ld, mod)
if prev, ok := firstPath[src]; !ok {
firstPath[src] = mod.Path
} else if prev != mod.Path {
pld.error(fmt.Errorf("%s@%s used for two different module paths (%s and %s)", src.Path, src.Version, prev, mod.Path))
}
}
}
// checkTidyCompatibility emits an error if any package would be loaded from a
// different module under rs than under ld.requirements.
func (pld *packageLoader) checkTidyCompatibility(ld *Loader, ctx context.Context, rs *Requirements, compatVersion string) {
goVersion := rs.GoVersion(ld)
suggestUpgrade := false
suggestEFlag := false
suggestFixes := func() {
if pld.AllowErrors {
// The user is explicitly ignoring these errors, so don't bother them with
// other options.
return
}
// We print directly to os.Stderr because this information is advice aboutView on GitHub (pinned to b6b368adc5)
Solutions
- Inspect go.mod and go.work 'replace' directives for two different module paths pointing at the same source.
- Ensure each module path maps to a distinct source directory or version.
- If using a local replacement, give each replaced module its own directory.
Example fix
// before (go.mod)
replace (
example.com/a => ./local
example.com/b => ./local
)
// after — distinct sources per module path
replace (
example.com/a => ./local-a
example.com/b => ./local-b
) Defensive patterns
Strategy: validation
Validate before calling
// Detect replace directives that alias distinct module paths to the same source.
func checkDuplicateReplaces(replacements []Replace) error {
seen := map[string]string{} // source -> first path
for _, r := range replacements {
src := r.New.Path + "@" + r.New.Version
if r.New.Version == "" {
src = r.New.Path // local replacement
}
if prev, ok := seen[src]; ok && prev != r.Old.Path {
return fmt.Errorf("%s used for two module paths (%s and %s)", src, prev, r.Old.Path)
}
seen[src] = r.Old.Path
}
return nil
} Prevention
- Ensure each 'replace' directive targets a distinct source directory or version.
- Avoid pointing multiple module paths at the same local directory in replace directives.
- Review 'go mod edit -print' for overlapping replacements before committing.
When it happens
Trigger: Two different module paths in the build list resolve (possibly via 'replace' directives) to the same filesystem source or the same module@version. For example, replace directives pointing distinct module paths at the same local directory, or a replacement that aliases module paths.
Common situations: Multiple 'replace' directives in go.mod pointing different module paths at the same local directory. A forked module published under a new path but accidentally sharing a version string with the original. Complex workspace setups with overlapping replacements.
Related errors
- %s (in %s): The go.mod file for the module providing named
- parsing go.mod: module declares its path as: %s bu
- parsing %s: %v
- ${GoModToolVersion} is required for tool directives in go.mo
- updates to go.mod needed, but go.mod is part of the overlay
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/78ed22f633e5e7f0.
Report an issue: GitHub.