{"record":{"id":"426403db2c92cc08","repo":"asdf-vm/asdf","slug":"s-is-invalid-name-may-only-contain-lowercase-let","errorCode":null,"errorMessage":"%s is invalid. Name may only contain lowercase letters, numbers, '_', and '-'","messagePattern":"(.+?) is invalid\\. Name may only contain lowercase letters, numbers, '_', and '-'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/plugins/plugins.go","lineNumber":504,"sourceCode":"\tif errors.Is(err, os.ErrNotExist) {\n\t\treturn false, nil\n\t}\n\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\treturn fileInfo.IsDir(), nil\n}\n\nfunc validatePluginName(name string) error {\n\tmatch, err := regexp.MatchString(\"^[[:lower:][:digit:]_-]+$\", name)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif !match {\n\t\treturn fmt.Errorf(invalidPluginNameMsg, name)\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":486,"sourceCodeEnd":509,"githubUrl":"https://github.com/asdf-vm/asdf/blob/074a1722ca88d6677f228541ce06efaf4f9924d4/internal/plugins/plugins.go#L486-L509","documentation":"asdf restricts plugin names to lowercase letters, digits, '_' and '-' (regexp ^[[:lower:][:digit:]_-]+$). validatePluginName runs at the top of Add and Remove; any name with uppercase letters, spaces, dots or other characters is rejected with this message naming the offending name. This keeps plugin names safe as directory names and hook suffixes.","triggerScenarios":"plugins.Add or plugins.Remove (or CLI add/remove) with names containing uppercase letters, spaces, dots (e.g. 'My.Plugin', 'node js'), or other non-matching characters.","commonSituations":"Copy-pasting a plugin repo name like 'asdf-nodejs' with different casing, using the plugin's display name with spaces, or interpolating a variable that is empty or contains slashes.","solutions":["Rename to lowercase, using '-' or '_' as separators (e.g. 'my-plugin')","Check for stray whitespace or hidden characters in the name argument","Validate/normalize the name in your own code before calling Add/Remove"],"exampleFix":"// before\nplugins.Add(conf, \"NodeJS\", url, \"\", os.Stdout)\n// after\nplugins.Add(conf, \"nodejs\", url, \"\", os.Stdout)","handlingStrategy":"validation","validationCode":"var pluginNameRe = regexp.MustCompile(`^[[:lower:][:digit:]_-]+$`)\nif !pluginNameRe.MatchString(name) {\n    return fmt.Errorf(\"invalid plugin name: %q\", name)\n}","typeGuard":"func validPluginName(name string) bool {\n    return regexp.MustCompile(`^[[:lower:][:digit:]_-]+$`).MatchString(name)\n}","tryCatchPattern":null,"preventionTips":["Normalize names to lowercase with '-'/'_' separators before calling Add/Remove","Trim whitespace from user-supplied plugin names"],"tags":["validation","naming","asdf"],"backgroundTag":"invalid-plugin-name","analyzedSha":"074a1722ca88d6677f228541ce06efaf4f9924d4","analyzedAt":"2026-08-30T19:56:42.972Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}