golang/go · error
%s (in %s): The go.mod file for the module providing named
Error message
%s (in %s): The go.mod file for the module providing named packages contains one or more %s directives. It must not contain directives that would cause it to be interpreted differently than if it were the main module.
What it means
The package@version install workflow runs in NoRoot mode (no main module). For safety it refuses modules whose go.mod contains `replace` directives, because replaces would change dependency resolution and make the result differ from how the module behaves as a main module. Only `replace`-free go.mod files are accepted.
Source
Thrown at src/cmd/go/internal/load/pkg.go:3459
return nil, fmt.Errorf("%s: %w", args[0], err)
}
if deprecation != "" {
fmt.Fprintf(os.Stderr, "go: module %s is deprecated: %s\n", rootMod.Path, modload.ShortMessage(deprecation, ""))
}
data, err := ld.Fetcher().GoMod(ctx, rootMod.Path, rootMod.Version)
if err != nil {
return nil, fmt.Errorf("%s: %w", args[0], err)
}
f, err := modfile.Parse("go.mod", data, nil)
if err != nil {
return nil, fmt.Errorf("%s (in %s): %w", args[0], rootMod, err)
}
directiveFmt := "%s (in %s):\n" +
"\tThe go.mod file for the module providing named packages contains one or\n" +
"\tmore %s directives. It must not contain directives that would cause\n" +
"\tit to be interpreted differently than if it were the main module."
if len(f.Replace) > 0 {
return nil, fmt.Errorf(directiveFmt, args[0], rootMod, "replace")
}
if len(f.Exclude) > 0 {
return nil, fmt.Errorf(directiveFmt, args[0], rootMod, "exclude")
}
// Since we are in NoRoot mode, the build list initially contains only
// the dummy command-line-arguments module. Add a requirement on the
// module that provides the packages named on the command line.
if _, err := modload.EditBuildList(ld, ctx, nil, []module.Version{rootMod}); err != nil {
return nil, fmt.Errorf("%s: %w", args[0], err)
}
// Load packages for all arguments.
pkgs := PackagesAndErrors(ld, ctx, opts, patterns)
// Check that named packages are all provided by the same module.
for _, pkg := range pkgs {
var pkgErr errorView on GitHub (pinned to b6b368adc5)
Solutions
- Choose a version of the module that does not contain replace directives (check `go list -m -json -versions` or the VCS tags).
- Clone the module locally and `go install` from within the checkout where it is the main module.
- Report to the maintainer that a released tag carries replace directives.
Defensive patterns
Strategy: validation
Validate before calling
// Inspect go.mod for replace directives before installing.
func hasReplaceDirective(mod, ver string) (bool, error) {
out, err := exec.Command("go", "mod", "download", "-json", mod+"@"+ver).Output()
if err != nil { return false, err }
var info struct{ GoMod string }
if err := json.Unmarshal(out, &info); err != nil { return false, err }
data, err := os.ReadFile(info.GoMod)
if err != nil { return false, err }
return bytes.Contains(data, []byte("replace ")), nil
} Prevention
- Pre-validate module versions you depend on for replace/exclude directives.
- Maintain an allowlist of vetted versions for automated installs.
- Prefer modules whose releases are tested without local replaces.
When it happens
Trigger: `go install example.com/pkg@v1.0.0` where example.com/pkg's published go.mod contains one or more `replace` directives.
Common situations: Module author accidentally left local `replace` directives in a tagged release; the module uses replaces internally for development.
Related errors
- %s: argument must be a clean package path
- %s: argument must not be a package in the standard library
- %s: %w
- %s (in %s): %w
- package %s not provided by module %s
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/a64eb27dc9c58f2f.
Report an issue: GitHub.