{"record":{"id":"e4d99c07a83bacaa","repo":"hashicorp/nomad","slug":"failed-to-convert-version-q-v","errorCode":null,"errorMessage":"failed to convert version %q : %v","messagePattern":"failed to convert version %q : (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"helper/pluginutils/loader/init.go","lineNumber":210,"sourceCode":"\tfor _, sv := range supportedVersions {\n\t\tfor _, pv := range pluginVersions {\n\t\t\tif sv.Equal(pv) {\n\t\t\t\treturn pv.Original(), nil\n\t\t\t}\n\t\t}\n\t}\n\n\treturn \"\", nil\n}\n\n// convertVersions takes a list of string versions and returns a sorted list of\n// versions from highest to lowest.\nfunc convertVersions(in []string) ([]*version.Version, error) {\n\tconverted := make([]*version.Version, len(in))\n\tfor i, v := range in {\n\t\tvv, err := version.NewVersion(v)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to convert version %q : %v\", v, err)\n\t\t}\n\n\t\tconverted[i] = vv\n\t}\n\n\tsort.Slice(converted, func(i, j int) bool {\n\t\treturn converted[i].GreaterThan(converted[j])\n\t})\n\n\treturn converted, nil\n}\n\n// scan scans the plugin directory and retrieves potentially eligible binaries\nfunc (l *PluginLoader) scan() ([]os.FileInfo, error) {\n\tif l.pluginDir == \"\" {\n\t\treturn nil, nil\n\t}\n","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/helper/pluginutils/loader/init.go#L192-L228","documentation":"convertVersions maps a []string of version strings to []*version.Version (sorted highest first) using hashicorp/go-version. It fails fast on the first string version.NewVersion cannot parse, wrapping the underlying parse error.","triggerScenarios":"Any of selectApiVersion, NewPluginLoader, or the internal anonymous helper passes a version string that go-version rejects (empty string, non-numeric, bad prerelease syntax).","commonSituations":"Hardcoded API version lists containing typos; environment/config-driven version strings interpolated incorrectly; using names like \"v1\" is fine but \"v 1\" or \"1.0.0.0\" is not.","solutions":["Correct the offending version string to valid semver (optional v prefix, numeric components)","Inspect the wrapped %v to identify the exact string that failed","Add a unit test that runs convertVersions (or version.NewVersion) over the declared version list"],"exampleFix":"// before\nconvertVersions([]string{\"v1.\", \"v2\"})\n// after\nconvertVersions([]string{\"v1.0.0\", \"v2.0.0\"})","handlingStrategy":"validation","validationCode":"vv, err := version.NewVersion(candidate)\nif err != nil {\n    return fmt.Errorf(\"version %q rejected: %w\", candidate, err)\n}","typeGuard":null,"tryCatchPattern":"if err := loader.Init(...); err != nil {\n    if strings.Contains(err.Error(), \"failed to convert version\") {\n        // scan all version strings with version.NewVersion to locate the bad one\n    }\n}","preventionTips":["Lint hardcoded version strings with a regex like ^v?\\d+\\.\\d+\\.\\d+$","Unit-test convertVersions on every declared version list","Avoid building version strings via string concatenation of config values"],"tags":["go","version-parsing","plugin-loader","nomad"],"backgroundTag":"invalid-version-string","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}