{"record":{"id":"8c161b42807a8e15","repo":"golang/go","slug":"preceding-tag-s-not-found","errorCode":null,"errorMessage":"preceding tag (%s) not found","messagePattern":"preceding tag \\((.+?)\\) not found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/modfetch/coderepo.go","lineNumber":784,"sourceCode":"\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar lastTag string // Prefer to log some real tag rather than a canonically-equivalent base.\n\tancestorFound := false\n\tfor _, tag := range tags.List {\n\t\tversionOnly := strings.TrimPrefix(tag.Name, tagPrefix)\n\t\tif semver.Compare(versionOnly, base) == 0 {\n\t\t\tlastTag = tag.Name\n\t\t\tancestorFound, err = r.code.DescendsFrom(ctx, info.Name, tag.Name)\n\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) {","sourceCodeStart":766,"sourceCodeEnd":802,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/modfetch/coderepo.go#L766-L802","documentation":"validatePseudoVersion (coderepo.go:765-785) calls r.code.Tags(ctx, tagPrefix+base) to enumerate tags matching the base version and walks them. If none of the returned tags has a version equal to base, lastTag stays empty and this error fires: the pseudo-version claims a preceding tag (its base) that does not exist anywhere in the repo.","triggerScenarios":"A pseudo-version embeds a base like v1.2.3 but the repo never had a v1.2.3 tag (e.g. it was deleted, or the base was fabricated). The tag-prefix lookup (for subdirectory modules, e.g. foo/v1.2.3) also fails.","commonSituations":"Upstream deleted a tag that older pseudo-versions referenced; pseudo-version was hand-built with an invented base; tags exist only under a different prefix (subdirectory module path mismatch).","solutions":["Verify the base tag exists: `git tag --list '<tagPrefix>v1.2.3*'` in the source repo.","Re-derive the pseudo-version from the real nearest ancestor tag (`go get <module>@<commit>`).","If you own the repo, restore or recreate the missing tag.","For subdirectory modules, confirm the tag prefix matches the module path major subdirectory."],"exampleFix":"// before (base v1.2.3 never tagged)\nrequire example.com/m v1.2.4-0.20240101120000-e3702bed3d42\n\n// after (base on a real ancestor tag)\nrequire example.com/m v1.2.3-0.20240101120000-e3702bed3d42   // if v1.2.3 exists\n// or pin to the real tag\nrequire example.com/m v1.2.3","handlingStrategy":"validation","validationCode":"// Confirm the base tag exists before referencing a pseudo-version.\n// bash:\n//   git tag --list '<tagPrefix>v1.2.3*'\n//   # if empty, the base does not exist; re-derive or recreate the tag\n//\n// Go: re-derive via tooling\n//   go get example.com/m@<commit>   // picks the highest real ancestor tag as base","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never delete upstream tags that old pseudo-versions reference.","Use `go get @<commit>` so the tool finds a real ancestor tag.","For subdirectory modules, ensure tags are namespaced under the module path."],"tags":["go-modules","pseudo-version","vcs-tags","validation"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}