{"record":{"id":"177223e2eb22c48e","repo":"kubernetes/kops","slug":"error-parsing-version-s-v-177223","errorCode":null,"errorMessage":"Error parsing version %s: %v","messagePattern":"Error parsing version (.+?): (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apis/kops/util/versions.go","lineNumber":53,"sourceCode":"\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to parse kubernetes version (%s): %w\", version, err)\n\t\t\t}\n\t\t\tsv = semver.Version{Major: 1, Minor: uint64(minor)}\n\t\t} else {\n\t\t\tklog.Errorf(\"unable to parse Kubernetes version %q\", version)\n\t\t\treturn nil, fmt.Errorf(\"unable to parse kubernetes version %q\", version)\n\t\t}\n\t\tklog.V(1).Infof(\"Kubernetes version %q string matched to %v\", version, sv)\n\t}\n\n\treturn &sv, nil\n}\n\n// Deprecated: prefer using KubernetesVersion.IsGTE()\nfunc IsKubernetesGTE(version string, k8sVersion semver.Version) bool {\n\tparsedVersion, err := ParseKubernetesVersion(version)\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"Error parsing version %s: %v\", version, err))\n\t}\n\n\t// Ignore Pre & Build fields\n\tk8sVersion.Pre = nil\n\tk8sVersion.Build = nil\n\n\treturn k8sVersion.GTE(*parsedVersion)\n}\n\n// Version is our helper type for semver versions.\ntype Version struct {\n\tv semver.Version\n}\n\n// ParseVersion parses the semver version string into a Version.\nfunc ParseVersion(s string) (*Version, error) {\n\tv, err := semver.Parse(s)\n\tif err != nil {","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/apis/kops/util/versions.go#L35-L71","documentation":"The deprecated IsKubernetesGTE(version, k8sVersion) helper panics when the version string argument fails ParseKubernetesVersion. Like its successor KubernetesVersion.IsGTE, the library treats an invalid version argument as an unrecoverable programming error. The function is deprecated precisely because this panic-based contract is unsafe.","triggerScenarios":"Calling IsKubernetesGTE with a malformed string such as \"1.21\" (no patch), \"\", \"latest\", or any non-semver text; the same string is used by tests Test_IsKubernetesGTE* and by validateKubernetesVersion paths.","commonSituations":"Legacy code still calling the deprecated function after upgrading kOps, version strings read from cluster config or user input, hardcoded constants with missing patch components.","solutions":["Stop using the deprecated IsKubernetesGTE; switch to a KubernetesVersion built via util.ParseKubernetesVersion so parse errors are returned, not panicked.","Fix the version literal to full semver with all three components (e.g. \"1.21.0\").","Pre-validate with ParseKubernetesVersion and handle err before calling.","Replace panic-prone comparisons in validation code with explicit error returns."],"exampleFix":"// before\nif kops.IsKubernetesGTE(\"1.24\", ver) { ... } // panics on bad input\n// after\nparsed, err := util.ParseKubernetesVersion(\"1.24.0\")\nif err != nil { return err }\n_ = parsed\n// or: kv.IsGTE(\"1.24.0\") on a parsed KubernetesVersion","handlingStrategy":"validation","validationCode":"if _, err := kops.ParseKubernetesVersion(version); err != nil {\n    return fmt.Errorf(\"invalid version %q: %w\", version, err)\n}\n// safe to call IsKubernetesGTE(version, k8sVersion) now","typeGuard":null,"tryCatchPattern":"// Go panics: guard with recover when touching deprecated APIs\nfunc safeGTE(version string, v semver.Version) (ok bool) {\n    defer func() {\n        if r := recover(); r != nil {\n            ok = false\n        }\n    }()\n    return kops.IsKubernetesGTE(version, v)\n}","preventionTips":["Migrate off deprecated IsKubernetesGTE to KubernetesVersion.IsGTE","Use major.minor.patch strings everywhere; reject short forms at input","Run staticcheck/linters to flag calls to deprecated functions","Cover version literals with table-driven tests"],"tags":["go","panic","deprecated","version-parsing","semver"],"backgroundTag":"invalid-version-string","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}