golang/go · error

revision is shorter than canonical (expected %s)

Error message

revision is shorter than canonical (expected %s)

What it means

Same validatePseudoVersion comparison (coderepo.go:694-703). This branch fires when info.Short starts with the embedded rev — the pseudo-version carries a shorter hash than the VCS's canonical short name. A too-short hash is ambiguous (could collide with another commit) and non-canonical, so the resolver refuses it.

Source

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

			if _, ok := err.(*module.ModuleError); !ok {
				if _, ok := err.(*module.InvalidVersionError); !ok {
					err = &module.InvalidVersionError{Version: version, Pseudo: true, Err: err}
				}
				err = &module.ModuleError{Path: r.modPath, Err: err}
			}
		}
	}()

	rev, err := module.PseudoVersionRev(version)
	if err != nil {
		return err
	}
	if rev != info.Short {
		switch {
		case strings.HasPrefix(rev, info.Short):
			return fmt.Errorf("revision is longer than canonical (expected %s)", info.Short)
		case strings.HasPrefix(info.Short, rev):
			return fmt.Errorf("revision is shorter than canonical (expected %s)", info.Short)
		default:
			return fmt.Errorf("does not match short name of revision (expected %s)", info.Short)
		}
	}

	t, err := module.PseudoVersionTime(version)
	if err != nil {
		return err
	}
	if !t.Equal(info.Time.Truncate(time.Second)) {
		return fmt.Errorf("does not match version-control timestamp (expected %s)", info.Time.UTC().Format(module.PseudoVersionTimestampFormat))
	}

	tagPrefix := ""
	if r.codeDir != "" {
		tagPrefix = r.codeDir + "/"
	}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Regenerate the version with the current toolchain: `go get <module>@<commit>` and let it embed the correct short hash.
  2. If the underlying repo's abbrev grew, update go.mod/go.sum to the re-derived pseudo-version.
  3. Avoid hand-truncating hashes in version strings.

Example fix

// before (7-char hash, no longer canonical)
require example.com/m v0.0.0-20240101120000-e3702bed

// after (current default short hash)
require example.com/m v0.0.0-20240101120000-e3702bed3d42
Defensive patterns

Strategy: validation

Validate before calling

// Reject pseudo-versions whose embedded hash is shorter than canonical.
// bash:
//   short=$(git rev-parse --short <commit>)
//   # if the pseudo-version's hash field is shorter than ${#short}, regenerate it
//
// Go:
package main
import ("golang.org/x/mod/module"; "strings")
func validateLen(pseudo, canonicalShort string) error {
    rev, err := module.PseudoVersionRev(pseudo)
    if err != nil { return err }
    if len(rev) < len(canonicalShort) {
        return fmt.Errorf("pseudo-version rev %s shorter than canonical %s", rev, canonicalShort)
    }
    return nil
}

Prevention

When it happens

Trigger: Hand-editing a pseudo-version to truncate the hash; an older toolchain generated pseudo-versions with fewer hex digits than the current default (git has progressively lengthened default short hashes over time); abbreviated hashes from a non-git VCS bridge.

Common situations: Pseudo-versions produced by old `go` versions when git's default abbrev was 7; repos where default abbrev grew to 12 after more commits; manual shortening for brevity.

Related errors


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