golang/go · error

%s has post-%s module path %q%s at revision %s

Error message

%s has post-%s module path %q%s at revision %s

What it means

findDir (coderepo.go:901-903). The root go.mod declares a module path that parses cleanly but whose declared major version is HIGHER than semver.Major(version) being resolved. Example: resolving v1.2.3 but go.mod says `module example.com/m/v2`. pathMajor is empty (no gopkg.in suffix) and the structural checks pass, so we reach this 'post-major' clause.

Source

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

		// 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
			return "", "", nil, fmt.Errorf("%s has non-...%s module path %q%s at revision %s", file1, r.pathMajor, mpath1, suffix, rev)
		}
		if _, _, ok := module.SplitPathVersion(mpath1); !ok {
			return "", "", nil, fmt.Errorf("%s has malformed module path %q%s at revision %s", file1, mpath1, suffix, rev)
		}
		return "", "", nil, fmt.Errorf("%s has post-%s module path %q%s at revision %s", file1, semver.Major(version), mpath1, suffix, rev)
	}

	if r.codeDir == "" && (r.pathMajor == "" || strings.HasPrefix(r.pathMajor, ".")) {
		// Implicit go.mod at root of repo OK for v0/v1 and for gopkg.in.
		return rev, "", nil, nil
	}

	// Implicit go.mod below root of repo or at v2+ disallowed.
	// Be clear about possibility of using either location for v2+.
	if file2 != "" {
		return "", "", nil, fmt.Errorf("missing %s/go.mod and ...%s/go.mod at revision %s", r.pathPrefix, r.pathMajor, rev)
	}
	return "", "", nil, fmt.Errorf("missing %s/go.mod at revision %s", r.pathPrefix, rev)
}

// isMajor reports whether the versions allowed for mpath are compatible with
// the major version(s) implied by pathMajor, or false if mpath has an invalid
// version suffix.

View on GitHub (pinned to b6b368adc5)

Solutions

  1. If the module uses in-place major bumps, request a v2 version (`go get example.com/m/v2@v2.x.x`).
  2. If using the major-subdir layout, ensure the v1 tag's go.mod still declares a v1 module path.
  3. Tag a corrected revision so the major version in go.mod matches the tag's major.

Example fix

// before
// go get example.com/m@v1.2.3   // but go.mod at v1.2.3 says module example.com/m/v2

// after
// go get example.com/m/v2@v2.0.0   // match the declared major
Defensive patterns

Strategy: validation

Validate before calling

// The major version of the request must be >= the major declared in go.mod.
// bash:
//   requested_major='v1'
//   declared_major=$(grep -oE '/v[0-9]+"?$' <(grep '^module ' go.mod) | tr -d '"')
//   # if declared_major > requested_major, the dependency is wrong
//
// Easier: let the toolchain resolve:
//   go get example.com/m/v2@v2.0.0   // import path includes /v2

Prevention

When it happens

Trigger: Depending on v1.x of a module whose go.mod at that revision already declares a v2 module path — i.e. the repo's go.mod was bumped to v2 before the v1 tag was made, or the wrong revision is being read.

Common situations: Major-version migration done in-place (root go.mod rewritten to /v2) while old v1 tags still point at pre-bump commits; requesting an old version after an in-place major bump; misaligned tags and go.mod state.

Related errors


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