golang/go · error

revision %s is not a descendent of preceding tag (%s)

Error message

revision %s is not a descendent of preceding tag (%s)

What it means

validatePseudoVersion (coderepo.go:787-796). A base tag was found, but r.code.DescendsFrom(info.Name, lastTag) returned false: the revision the pseudo-version names is not a descendant of the tag the pseudo-version claims as its base. Pseudo-versions must be based on an ancestor tag so that version ordering stays meaningful (prevents 'pinning' via inflated pseudo-versions).

Source

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

			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
		}
		return r.codeDir + "/" + rev
	}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Re-derive the pseudo-version so its base is a genuine ancestor: `go get <module>@<commit>` (the tool finds the highest ancestor tag).
  2. If using a shallow mirror, switch to a full clone or a proxy that serves complete history.
  3. Verify ancestry manually: `git merge-base --is-ancestor <tag> <commit>`.

Example fix

// before (v1.2.3 is NOT an ancestor of the named commit)
require example.com/m v1.2.3-0.20240101120000-e3702bed3d42

// after (use a tag that IS an ancestor)
require example.com/m v1.2.2-0.20240101120000-e3702bed3d42
Defensive patterns

Strategy: validation

Validate before calling

// Verify the base tag is an ancestor of the commit.
// bash:
//   git merge-base --is-ancestor <base-tag> <commit> && echo OK || echo NOT-ANCESTOR
//
// If NOT-ANCESTOR, choose a different base tag that is.

Prevention

When it happens

Trigger: A pseudo-version was built from tag v1.2.3 but points at a commit that predates or branches off before v1.2.3; history was rewritten so the tag is no longer an ancestor; cherry-pick workflows where the pseudo-version's base tag is on an unrelated branch.

Common situations: Rebasing or squashing that removes the ancestor relationship; selecting a base tag from the wrong branch; force-pushes invalidating ancestry; mirrors with truncated history (shallow clones).

Related errors


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