golang/go · error · PackageError

package %s provided by module %s@%s All packages must be pr

Error message

package %s provided by module %s@%s
	All packages must be provided by the same module (%s).

What it means

A loaded package's `Module` differs in path or version from the `rootMod` resolved from the first argument. The package@version workflow requires ALL package arguments to be provided by the SAME module at the SAME version. This fires when arguments span multiple modules (common in multi-module repositories).

Source

Thrown at src/cmd/go/internal/load/pkg.go:3483

	// 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 error
		if pkg.Module == nil {
			// Packages in std, cmd, and their vendored dependencies
			// don't have this field set.
			pkgErr = fmt.Errorf("package %s not provided by module %s", pkg.ImportPath, rootMod)
		} else if pkg.Module.Path != rootMod.Path || pkg.Module.Version != rootMod.Version {
			pkgErr = fmt.Errorf("package %s provided by module %s@%s\n\tAll packages must be provided by the same module (%s).", pkg.ImportPath, pkg.Module.Path, pkg.Module.Version, rootMod)
		}
		if pkgErr != nil && pkg.Error == nil {
			pkg.Error = &PackageError{Err: pkgErr}
			pkg.Incomplete = true
		}
	}

	matchers := make([]func(string) bool, len(patterns))
	for i, p := range patterns {
		if strings.Contains(p, "...") {
			matchers[i] = pkgpattern.MatchPattern(p)
		}
	}
	return pkgs, nil
}

// EnsureImport ensures that package p imports the named package.
func EnsureImport(s *modload.Loader, p *Package, pkg string) {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Ensure every argument belongs to the same module path prefix as the first argument.
  2. Split the install into separate `go install moduleA/...@vA` and `go install moduleB/...@vB` invocations.
  3. Use `go list -m` per package to confirm module boundaries before constructing the command.

Example fix

// before
go install example.com/mod/a example.com/sibling/b@v1.0.0

// after
go install example.com/mod/a@v1.0.0
go install example.com/sibling/b@v1.0.0
Defensive patterns

Strategy: validation

Validate before calling

// Ensure all package args share the same module prefix.
func sameModule(args []string, mod string) bool {
    for _, a := range args {
        p, _, _ := strings.Cut(a, "@")
        if !strings.HasPrefix(p, mod+"/") && p != mod {
            return false
        }
    }
    return true
}

Prevention

When it happens

Trigger: `go install example.com/mod/pkg1 example.com/othermod/pkg2@v1.0.0` where pkg2 lives in a different module; a `...` wildcard in a multi-module repo crosses module boundaries.

Common situations: Multi-module repositories (several go.mod files in one VCS); passing packages from sibling modules; wildcards that escape the root module's tree.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/3a51096f1a14fa75. Report an issue: GitHub.