golang/go · error

%s: all arguments must refer to packages in the same module

Error message

%s: all arguments must refer to packages in the same module at the same version (@%s)

What it means

Returned by PackagesAndErrorsOutsideModule (line 3401) during the second pass over args. Once a version is established from the first '@'-bearing arg, EVERY other arg must end with that exact `@<version>` suffix (strings.CutSuffix). If CutSuffix fails for any arg, that arg is not in the same module at the same version, which the function forbids to avoid ambiguity. The echoed @<version> is the canonical suffix expected.

Source

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

	}

	// Check that the arguments satisfy syntactic constraints.
	var version string
	var firstPath string
	for _, arg := range args {
		if i := strings.Index(arg, "@"); i >= 0 {
			firstPath, version = arg[:i], arg[i+1:]
			if version == "" {
				return nil, fmt.Errorf("%s: version must not be empty", arg)
			}
			break
		}
	}
	patterns := make([]string, len(args))
	for i, arg := range args {
		p, found := strings.CutSuffix(arg, "@"+version)
		if !found {
			return nil, fmt.Errorf("%s: all arguments must refer to packages in the same module at the same version (@%s)", arg, version)
		}
		switch {
		case build.IsLocalImport(p):
			return nil, fmt.Errorf("%s: argument must be a package path, not a relative path", arg)
		case filepath.IsAbs(p):
			return nil, fmt.Errorf("%s: argument must be a package path, not an absolute path", arg)
		case search.IsMetaPackage(p):
			return nil, fmt.Errorf("%s: argument must be a package path, not a meta-package", arg)
		case pathpkg.Clean(p) != p:
			return nil, fmt.Errorf("%s: argument must be a clean package path", arg)
		case !strings.Contains(p, "...") && search.IsStandardImportPath(p) && modindex.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, p):
			return nil, fmt.Errorf("%s: argument must not be a package in the standard library", arg)
		default:
			patterns[i] = p
		}
	}
	patterns = search.CleanPatterns(patterns)

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Give every argument the identical `@<version>` suffix.
  2. If the packages genuinely live in different modules/versions, run separate `go install` invocations.
  3. Verify with `go list -m` which module each package belongs to before combining them.

Example fix

# before
go install example.com/app/cmd/a@v1.0.0 example.com/app/cmd/b
# after
go install example.com/app/cmd/a@v1.0.0 example.com/app/cmd/b@v1.0.0
Defensive patterns

Strategy: validation

Validate before calling

// Confirm every arg in a multi-arg `go install pkg@version` carries the
// SAME @<version> suffix.
package argcheck

import (
	"errors"
	"strings"
)

func UniformVersion(args []string) error {
	var version string
	for _, a := range args {
		if i := strings.Index(a, "@"); i >= 0 {
			version = a[i:]
			break
		}
	}
	if version == "" {
		return errors.New("no @version found on any arg")
	}
	for _, a := range args {
		if !strings.HasSuffix(a, version) {
			return errors.New("arg " + a + " lacks shared version " + version)
		}
	}
	return nil
}

Prevention

When it happens

Trigger: Mixing versions in one `go install` command: `go install example.com/a@v1.0.0 example.com/b@v2.0.0`; or forgetting the @version on a second arg: `go install mod/a@v1.0.0 mod/b`.

Common situations: Installing several binaries and assuming they share a version; CI matrix scripts concatenating differently-versioned args; refactoring a multi-binary install line.

Related errors


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