golang/go · error

invalid version %q

Error message

invalid version %q

What it means

Thrown by `Fetcher.InfoFile` when `gover.ModIsValid(path, version)` returns false. InfoFile returns the cached RevInfo (revision info) and the file path containing it. A non-semver version cannot be looked up in the disk cache since the cache path encoding requires a valid version. This is the entry point for getting module revision metadata.

Source

Thrown at src/cmd/go/internal/modfetch/cache.go:349

	})
	if err != nil {
		return nil, err
	}
	return append([]byte(nil), text...), nil
}

func (r *cachingRepo) Zip(ctx context.Context, dst io.Writer, version string) error {
	if gover.IsToolchain(r.path) {
		return ErrToolchain
	}
	return r.repo(ctx).Zip(ctx, dst, version)
}

// InfoFile is like Lookup(ctx, path).Stat(version) but also returns the name of the file
// containing the cached information.
func (f *Fetcher) InfoFile(ctx context.Context, path, version string) (*RevInfo, string, error) {
	if !gover.ModIsValid(path, version) {
		return nil, "", fmt.Errorf("invalid version %q", version)
	}

	if file, info, err := readDiskStat(ctx, path, version); err == nil {
		return info, file, nil
	}

	var info *RevInfo
	var err2info map[error]*RevInfo
	err := TryProxies(func(proxy string) error {
		i, err := f.Lookup(ctx, proxy, path).Stat(ctx, version)
		if err == nil {
			info = i
		} else {
			if err2info == nil {
				err2info = make(map[error]*RevInfo)
			}
			err2info[err] = info
		}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Resolve symbolic versions first: call `Lookup(path).Stat(ctx, "latest")` to get a concrete version
  2. Validate with `gover.ModIsValid(path, version)` before calling InfoFile
  3. Use the higher-level modfetch.Lookup chain that handles version resolution

Example fix

// before
info, file, err := f.InfoFile(ctx, path, "latest")
// after
revInfo, _ := f.Lookup(ctx, proxy, path).Stat(ctx, "latest")
info, file, err := f.InfoFile(ctx, path, revInfo.Version)
Defensive patterns

Strategy: validation

Validate before calling

import "golang.org/x/mod/gover"

func safeInfoFile(ctx context.Context, f *modfetch.Fetcher, path, version string) (*modfetch.RevInfo, string, error) {
    if !gover.ModIsValid(path, version) {
        return nil, "", fmt.Errorf("invalid version %q for path %q", version, path)
    }
    return f.InfoFile(ctx, path, version)
}

Prevention

When it happens

Trigger: Calling `fetcher.InfoFile(ctx, path, version)` with an invalid version string — not valid semver, not a recognized pseudo-version, not properly formatted for the module path. The version must pass ModIsValid before disk lookup or proxy queries.

Common situations: Passing 'latest' or 'HEAD' directly to InfoFile (these are symbolic and must be resolved via Stat first); malformed version strings from user input; bugs in version construction in calling code.

Related errors


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