{"record":{"id":"cd6af173850e6a5e","repo":"larksuite/cli","slug":"non-numeric-component-q-in-version-q","errorCode":null,"errorMessage":"non-numeric component %q in version %q","messagePattern":"non-numeric component %q in version %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/platform/version.go","lineNumber":137,"sourceCode":"\t\tif c == '-' || c == '+' {\n\t\t\ts = s[:i]\n\t\t\tbreak\n\t\t}\n\t}\n\tfields := strings.Split(s, \".\")\n\t// Reject `1.2.3.4` and longer instead of silently truncating —\n\t// truncation hides the typo and lets a malformed RequiredCLIVersion\n\t// pass validation while the comparator below operates on the wrong\n\t// components. Build-version parsing has its own fail-open guard\n\t// upstream (see satisfiesRequiredCLIVersion comment about exotic\n\t// build tags), so it stays compatible.\n\tif len(fields) > 3 {\n\t\treturn [3]int{}, fmt.Errorf(\"version %q has more than three numeric components\", s)\n\t}\n\tfor i, f := range fields {\n\t\tn, err := strconv.Atoi(strings.TrimSpace(f))\n\t\tif err != nil || n < 0 {\n\t\t\treturn [3]int{}, fmt.Errorf(\"non-numeric component %q in version %q\", f, s)\n\t\t}\n\t\tparts[i] = n\n\t}\n\treturn parts, nil\n}\n\nfunc compareSemver(a, b [3]int) int {\n\tfor i := 0; i < 3; i++ {\n\t\tif a[i] < b[i] {\n\t\t\treturn -1\n\t\t}\n\t\tif a[i] > b[i] {\n\t\t\treturn 1\n\t\t}\n\t}\n\treturn 0\n}\n","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/platform/version.go#L119-L155","documentation":"Each dot-separated component of the version must parse via strconv.Atoi as a non-negative integer. This error is thrown when a component is not numeric, e.g. \"1.x.3\". Pre-release/build suffixes must be attached with '-' or '+' so they are trimmed before splitting, not placed after a dot.","triggerScenarios":"Calling satisfiesRequiredCLIVersion with versions like \"1.beta\", \"1..2\" (empty component), \"1.2.3.rc1\" (suffix after a dot instead of a dash), or strings containing stray letters/spaces.","commonSituations":"Writing pre-release tags after dots instead of dashes; typos like 'O' vs '0'; copy-paste including units or labels like \"1.2.3 LTS\"; corrupted config values.","solutions":["Use only digits in each dot-separated component; express pre-releases with a dash: \"1.2.3-rc1\", not \"1.2.3.rc1\".","Fix typos or stray characters in the version string.","If the value comes from registry meta or env, re-fetch/regenerate it to overwrite the corrupted entry."],"exampleFix":"// before\nrequiredCLIVersion = \"1.2.3.rc1\"\n// after\nrequiredCLIVersion = \"1.2.3-rc1\"","handlingStrategy":"validation","validationCode":"func numericComponents(s string) bool {\n\ts = strings.TrimPrefix(strings.TrimSpace(s), \"v\")\n\tif i := strings.IndexAny(s, \"-+\"); i >= 0 { s = s[:i] }\n\tfor _, f := range strings.Split(s, \".\") {\n\t\tif _, err := strconv.Atoi(f); err != nil { return false }\n\t}\n\treturn true\n}","typeGuard":"func isPlainSemver(s string) bool { m, _ := regexp.MatchString(`^v?\\d+(\\.\\d+){0,2}(-[^+]+)?(\\+.*)?$`, s); return m }","tryCatchPattern":"parts, err := parseSemverPrefix(v)\nif err != nil {\n\tvar msg string\n\tif _, aerr := strconv.Atoi(v); aerr != nil { msg = \"non-numeric version component\" }\n\treturn fmt.Errorf(\"%s: %w\", msg, err)\n}","preventionTips":["Attach pre-release/build tags with '-' or '+', never a dot.","Regex-validate version fields before persisting them to config.","Avoid copy-pasting labeled versions like \"1.2.3 LTS\"."],"tags":["version-parsing","config"],"backgroundTag":"invalid-version-format","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}