{"record":{"id":"fee9ba4934cb44cc","repo":"jeessy2/ddns-go","slug":"the-s-it-s-not-a-semantic-version","errorCode":null,"errorMessage":"the %s, it's not a semantic version","messagePattern":"the (.+?), it's not a semantic version","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/semver/version.go","lineNumber":37,"sourceCode":"\t`(-([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?` +\n\t`(\\+([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?`\n\n// Version 表示单独的语义化版本。\ntype Version struct {\n\tmajor, minor, patch uint64\n}\n\nfunc init() {\n\tversionRegex = regexp.MustCompile(\"^\" + semVerRegex + \"$\")\n}\n\n// NewVersion 解析给定的版本并返回 Version 实例，如果\n// 无法解析该版本则返回错误。如果版本是类似于 SemVer 的版本，则会\n// 尝试将其转换为 SemVer。\nfunc NewVersion(v string) (*Version, error) {\n\tm := versionRegex.FindStringSubmatch(v)\n\tif m == nil {\n\t\treturn nil, fmt.Errorf(\"the %s, it's not a semantic version\", v)\n\t}\n\n\tsv := &Version{}\n\n\tvar err error\n\tsv.major, err = strconv.ParseUint(m[1], 10, 64)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"解析版本号时出错：%s\", err)\n\t}\n\n\tif m[2] != \"\" {\n\t\tsv.minor, err = strconv.ParseUint(strings.TrimPrefix(m[2], \".\"), 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"解析版本号时出错：%s\", err)\n\t\t}\n\t} else {\n\t\tsv.minor = 0\n\t}","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/jeessy2/ddns-go/blob/5874c2e6667c69357ab95079421131104bd3fcae/util/semver/version.go#L19-L55","documentation":"NewVersion parses a version string and returns an error when the input does not match the semantic-version regex. The library attempts to coerce SemVer-like strings, but if the regex (versionRegex.FindStringSubmatch) finds no match it rejects the input with this message including the offending string. It is thrown at parse time, before any numeric field parsing.","triggerScenarios":"Calling util/semver.NewVersion with a string that does not match the semver pattern, e.g. \"abc\", \"\", \"1.2.3.4.5\", \"v\" alone, or a string with invalid characters — commonly when comparing current vs latest version strings obtained from untrusted sources.","commonSituations":"Update checkers feeding raw release names/URLs instead of clean version numbers; empty version output from a version command; pre-release or build metadata formats the regex rejects; locale-prefixed strings like \"version 1.2.3\".","solutions":["Print/validate the input string before parsing — the offending value is quoted in the error message","Trim prefixes like \"v\" or surrounding whitespace and strip non-semver text before calling NewVersion","Use the library's coercion-friendly format (major[.minor][.patch]) e.g. convert \"1.2\" or \"1\" instead of arbitrary strings","Fall back to a default version or skip comparison when the string is unparseable"],"exampleFix":"// before\nv, err := NewVersion(output) // output = \"version 1.2.3\"\n// after\ntrimmed := strings.TrimSpace(strings.TrimPrefix(output, \"version \"))\nv, err := NewVersion(trimmed)","handlingStrategy":"validation","validationCode":"func looksSemver(v string) bool {\n    v = strings.TrimSpace(strings.TrimPrefix(v, \"v\"))\n    parts := strings.Split(v, \".\")\n    if len(parts) == 0 || len(parts) > 3 { return false }\n    for _, p := range parts {\n        if p == \"\" { return false }\n        if _, err := strconv.ParseUint(p, 10, 64); err != nil { return false }\n    }\n    return true\n}","typeGuard":null,"tryCatchPattern":"v, err := semver.NewVersion(input)\nif err != nil {\n    log.Warnf(\"unparseable version %q, skipping comparison\", input)\n    return nil // or use a default version\n}","preventionTips":["Trim \"v\" prefixes and whitespace from version strings before parsing","Never feed raw release titles or URLs into NewVersion","Validate externally sourced versions with a regex before parsing","Log the raw input when parsing fails to ease diagnosis"],"tags":["semver","parsing","validation"],"backgroundTag":"invalid-semver-string","analyzedSha":"5874c2e6667c69357ab95079421131104bd3fcae","analyzedAt":"2026-09-03T15:41:16.799Z","contentChangedAt":"2026-09-03T15:41:16.799Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}