{"record":{"id":"19742300c1f84e4e","repo":"golang/go","slug":"revision-s-is-not-a-descendent-of-preceding-tag","errorCode":null,"errorMessage":"revision %s is not a descendent of preceding tag (%s)","messagePattern":"revision (.+?) is not a descendent of preceding tag \\((.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/modfetch/coderepo.go","lineNumber":795,"sourceCode":"\t\t\tif ancestorFound {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tif lastTag == \"\" {\n\t\treturn fmt.Errorf(\"preceding tag (%s) not found\", base)\n\t}\n\n\tif !ancestorFound {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trev, err := module.PseudoVersionRev(version)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"not a descendent of preceding tag (%s)\", lastTag)\n\t\t}\n\t\treturn fmt.Errorf(\"revision %s is not a descendent of preceding tag (%s)\", rev, lastTag)\n\t}\n\treturn nil\n}\n\nfunc (r *codeRepo) revToRev(rev string) string {\n\tif semver.IsValid(rev) {\n\t\tif module.IsPseudoVersion(rev) {\n\t\t\tr, _ := module.PseudoVersionRev(rev)\n\t\t\treturn r\n\t\t}\n\t\tif semver.Build(rev) == \"+incompatible\" {\n\t\t\trev = rev[:len(rev)-len(\"+incompatible\")]\n\t\t}\n\t\tif r.codeDir == \"\" {\n\t\t\treturn rev\n\t\t}\n\t\treturn r.codeDir + \"/\" + rev\n\t}","sourceCodeStart":777,"sourceCodeEnd":813,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/modfetch/coderepo.go#L777-L813","documentation":"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).","triggerScenarios":"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.","commonSituations":"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).","solutions":["Re-derive the pseudo-version so its base is a genuine ancestor: `go get <module>@<commit>` (the tool finds the highest ancestor tag).","If using a shallow mirror, switch to a full clone or a proxy that serves complete history.","Verify ancestry manually: `git merge-base --is-ancestor <tag> <commit>`."],"exampleFix":"// before (v1.2.3 is NOT an ancestor of the named commit)\nrequire example.com/m v1.2.3-0.20240101120000-e3702bed3d42\n\n// after (use a tag that IS an ancestor)\nrequire example.com/m v1.2.2-0.20240101120000-e3702bed3d42","handlingStrategy":"validation","validationCode":"// Verify the base tag is an ancestor of the commit.\n// bash:\n//   git merge-base --is-ancestor <base-tag> <commit> && echo OK || echo NOT-ANCESTOR\n//\n// If NOT-ANCESTOR, choose a different base tag that is.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid rebasing/squashing branches that carry tags referenced by pseudo-versions.","Use full clones (not shallow) for VCS hosts serving Go modules.","Re-derive pseudo-versions after any history rewrite."],"tags":["go-modules","pseudo-version","vcs-tags","history-rewrite"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}