{"record":{"id":"834c9e5276687ed7","repo":"golang/go","slug":"invalid-semantic-version-q-in-range-q","errorCode":null,"errorMessage":"invalid semantic version %q in range %q","messagePattern":"invalid semantic version %q in range %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/modload/query.go","lineNumber":430,"sourceCode":"\tprefix             string\n\tfilter             func(version string) bool\n\tallowed            AllowedFunc\n\tcanStat            bool // if true, the query can be resolved by repo.Stat\n\tpreferLower        bool // if true, choose the lowest matching version\n\tmayUseLatest       bool\n\tpreferIncompatible bool\n}\n\nvar errRevQuery = errors.New(\"query refers to a non-semver revision\")\n\n// newQueryMatcher returns a new queryMatcher that matches the versions\n// specified by the given query on the module with the given path.\n//\n// If the query can only be resolved by statting a non-SemVer revision,\n// newQueryMatcher returns errRevQuery.\nfunc newQueryMatcher(path string, query, current string, allowed AllowedFunc) (*queryMatcher, error) {\n\tbadVersion := func(v string) (*queryMatcher, error) {\n\t\treturn nil, fmt.Errorf(\"invalid semantic version %q in range %q\", v, query)\n\t}\n\n\tmatchesMajor := func(v string) bool {\n\t\t_, pathMajor, ok := module.SplitPathVersion(path)\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\t\treturn module.CheckPathMajor(v, pathMajor) == nil\n\t}\n\n\tqm := &queryMatcher{\n\t\tpath:               path,\n\t\tallowed:            allowed,\n\t\tpreferIncompatible: strings.HasSuffix(current, \"+incompatible\"),\n\t}\n\n\tswitch {\n\tcase query == \"latest\":","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/modload/query.go#L412-L448","documentation":"Returned by newQueryMatcher via the badVersion closure when a range-style query (<=, <, >=, >) contains a version operand that fails gover.ModIsValid for the module path. The matcher refuses to interpret an invalid semver as a range bound.","triggerScenarios":"Issuing a version-range query like 'go get example.com/pkg@<=foo' or '@<v1.x' where the bound is not a valid semantic version for the module path.","commonSituations":"Typos in a version range passed to 'go get'/'go list -m -versions'; scripting that interpolates an unvalidated string into a range query; mixing branch names into semver range bounds.","solutions":["Correct the bound to a canonical semver: vMAJOR.MINOR.PATCH (e.g. '<=v1.5.0', '<v2.0.0').","Validate the version string with semver.IsValid before constructing the query.","Use a plain '@<version>' or '@latest' instead of a range if you only need one version."],"exampleFix":"// before\n$ go get example.com/pkg@<=1.5\n// error: invalid semantic version \"1.5\" in range \"<=1.5\"\n\n// after\n$ go get example.com/pkg@<=v1.5.0","handlingStrategy":"validation","validationCode":"// Validate a range bound before constructing the query:\n//   if !gover.ModIsValid(path, bound) {\n//       return fmt.Errorf(\"invalid version bound %q\", bound)\n//   }","typeGuard":"func isValidRangeBound(path, v string) bool {\n    return gover.ModIsValid(path, v)\n}","tryCatchPattern":null,"preventionTips":["Always use canonical semver (vMAJOR.MINOR.PATCH) in range queries.","Sanitize user-supplied version strings through semver.IsValid before use.","Prefer '@<version>' over ranges unless a range is genuinely needed."],"tags":["go-modules","query","semver","validation"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}