golang/go · error

%s/%s has non-...%s module path %q at revision %s

Error message

%s/%s has non-...%s module path %q at revision %s

What it means

findDir (coderepo.go:877-879). The major-subdir go.mod (file2) was read successfully and declares a module path (mpath2 != ""), but isMajor(mpath2, pathMajor) is false — the declared path's major-version suffix does not match the expected pathMajor (e.g. /v2/go.mod says `module example.com/m/v3`).

Source

Thrown at src/cmd/go/internal/modfetch/coderepo.go:878

		file2 = path.Join(dir2, "go.mod")
		gomod2, err2 := r.code.ReadFile(ctx, rev, file2, codehost.MaxGoMod)
		if err2 != nil && !os.IsNotExist(err2) {
			return "", "", nil, fmt.Errorf("reading %s/%s at revision %s: %v", r.codeRoot, file2, rev, err2)
		}
		mpath2 := modfile.ModulePath(gomod2)
		found2 := err2 == nil && isMajor(mpath2, r.pathMajor)

		if found1 && found2 {
			return "", "", nil, fmt.Errorf("%s/%s and ...%s/go.mod both have ...%s module paths at revision %s", r.pathPrefix, file1, r.pathMajor, r.pathMajor, rev)
		}
		if found2 {
			return rev, dir2, gomod2, nil
		}
		if err2 == nil {
			if mpath2 == "" {
				return "", "", nil, fmt.Errorf("%s/%s is missing module path at revision %s", r.codeRoot, file2, rev)
			}
			return "", "", nil, fmt.Errorf("%s/%s has non-...%s module path %q at revision %s", r.codeRoot, file2, r.pathMajor, mpath2, rev)
		}
	}

	// Not v2/go.mod, so it's either go.mod or nothing. Which is it?
	if found1 {
		// Explicit go.mod with matching major version ok.
		return rev, r.codeDir, gomod1, nil
	}
	if err1 == nil {
		// Explicit go.mod with non-matching major version disallowed.
		suffix := ""
		if file2 != "" {
			suffix = fmt.Sprintf(" (and ...%s/go.mod does not exist)", r.pathMajor)
		}
		if mpath1 == "" {
			return "", "", nil, fmt.Errorf("%s is missing module path%s at revision %s", file1, suffix, rev)
		}
		if r.pathMajor != "" { // ".v1", ".v2" for gopkg.in

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Make the module path in the subdirectory go.mod match the directory's major suffix (e.g. `v2/go.mod` must declare `module …/v2`).
  2. If the subdirectory is the wrong location, move it to match the declared module path.
  3. Re-tag and re-resolve after the fix.

Example fix

// before: v2/go.mod
//   module example.com/m/v3
//
// after: v2/go.mod
//   module example.com/m/v2
Defensive patterns

Strategy: validation

Validate before calling

// The module path in <subdir>/go.mod must match the subdir's major suffix.
// bash:
//   # for v2/go.mod, the module line must end in /v2
//   grep -H '^module ' v*/go.mod
// CI check (one-liner):
//   for f in v*/go.mod; do major=$(basename "$(dirname "$f")"); \
//     grep -qE "^module .+/${major}$" "$f" || echo "mismatch in $f"; done

Prevention

When it happens

Trigger: The major subdirectory go.mod declares a different major version than its location implies: /v2/go.mod with `module …/v3`, or /v3/go.mod with `module …/v2`, or any non-matching suffix.

Common situations: Renaming a major-version subdirectory without updating the module directive; copy-pasting go.mod between major branches; misconfigured multi-module repos.

Related errors


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