golang/go · error

not a descendent of preceding tag (%s)

Error message

not a descendent of preceding tag (%s)

What it means

validatePseudoVersion (coderepo.go:787-794). A tag matching base was found (so lastTag is set) but r.code.DescendsFrom reported the revision is NOT a descendant of it, AND module.PseudoVersionRev failed to extract a revision from the version string. This is a secondary failure: the more specific 'revision %s is not a descendent…' message could not be produced because the rev could not be parsed.

Source

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

			lastTag = tag.Name
			ancestorFound, err = r.code.DescendsFrom(ctx, info.Name, tag.Name)
			if ancestorFound {
				break
			}
		}
	}

	if lastTag == "" {
		return fmt.Errorf("preceding tag (%s) not found", base)
	}

	if !ancestorFound {
		if err != nil {
			return err
		}
		rev, err := module.PseudoVersionRev(version)
		if err != nil {
			return fmt.Errorf("not a descendent of preceding tag (%s)", lastTag)
		}
		return fmt.Errorf("revision %s is not a descendent of preceding tag (%s)", rev, lastTag)
	}
	return nil
}

func (r *codeRepo) revToRev(rev string) string {
	if semver.IsValid(rev) {
		if module.IsPseudoVersion(rev) {
			r, _ := module.PseudoVersionRev(rev)
			return r
		}
		if semver.Build(rev) == "+incompatible" {
			rev = rev[:len(rev)-len("+incompatible")]
		}
		if r.codeDir == "" {
			return rev
		}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Re-derive the pseudo-version with `go get <module>@<commit>`.
  2. Validate the pseudo-version shape with `module.PseudoVersionRev` / `PseudoVersionTime` before recording it.
  3. If you need a non-descendant revision, use a pseudo-version based on a tag that IS an ancestor.

Example fix

// before (malformed rev field AND not a descendant of v1.2.3)
require example.com/m v1.2.4-0.20240101120000-not-a-hash

// after (well-formed and based on an ancestor tag)
require example.com/m v1.2.3-0.20240101120000-e3702bed3d42
Defensive patterns

Strategy: validation

Validate before calling

// Reject malformed pseudo-versions before recording them.
// Go:
package main
import "golang.org/x/mod/module"
func validate(pseudo string) error {
    if _, err := module.PseudoVersionRev(pseudo); err != nil { return err }
    if _, err := module.PseudoVersionTime(pseudo); err != nil { return err }
    if _, err := module.PseudoVersionBase(pseudo); err != nil { return err }
    return nil
}

Prevention

When it happens

Trigger: The pseudo-version is structurally malformed such that PseudoVersionRev returns an error, AND the ancestor check against an existing base tag failed. Rare; usually preceded by a separate syntax error.

Common situations: Hand-editing the pseudo-version so the rev field is unparseable; combined corruption of timestamp and rev fields; older pseudo-version formats no longer accepted by newer toolchains.

Related errors


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