{"record":{"id":"25157056f8e73925","repo":"helm/helm","slug":"not-a-directory-251570","errorCode":null,"errorMessage":"not a directory","messagePattern":"not a directory","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/chart/v3/lint/rules/template.go","lineNumber":218,"sourceCode":"\treturn scanner.Err()\n}\n\n// Validation functions\nfunc templatesDirExists(templatesPath string) error {\n\t_, err := os.Stat(templatesPath)\n\tif errors.Is(err, os.ErrNotExist) {\n\t\treturn errors.New(\"directory does not exist\")\n\t}\n\treturn nil\n}\n\nfunc validateTemplatesDir(templatesPath string) error {\n\tfi, err := os.Stat(templatesPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !fi.IsDir() {\n\t\treturn errors.New(\"not a directory\")\n\t}\n\treturn nil\n}\n\nfunc validateAllowedExtension(fileName string) error {\n\text := filepath.Ext(fileName)\n\tvalidExtensions := []string{\".yaml\", \".yml\", \".tpl\", \".txt\"}\n\n\tif slices.Contains(validExtensions, ext) {\n\t\treturn nil\n\t}\n\n\treturn fmt.Errorf(\"file extension '%s' not valid. Valid extensions are .yaml, .yml, .tpl, or .txt\", ext)\n}\n\nfunc validateYamlContent(err error) error {\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to parse YAML: %w\", err)","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/helm/helm/blob/2a29f1770b62844b27197d2507377361d45ad7c0/internal/chart/v3/lint/rules/template.go#L200-L236","documentation":"setIndex (pkg/strvals/parser.go:308) rejects negative indexes with this message. For normal --set input this guard is shadowed by the earlier check in parser.listItem (parser.go:335), so seeing it means setIndex was reached with i < 0 directly — typically the same malformed input ('a[-1]=v') but observed from the lower-level call path, or a program calling setIndex-shaped flows via the public Parse APIs on unusual input.","triggerScenarios":"strvals.Parse(\"a[-1]=v\") normally surfaces the listItem variant; this variant appears when the negative index reaches setIndex itself, e.g. through nested paths or direct library use patterns.","commonSituations":"Same as negative-index errors generally: negative indexing expectations, bad interpolation producing -1, off-by-one loop counters.","solutions":["Use a non-negative 0-based index","Compute the correct index client-side instead of relying on negative semantics","Validate bracket contents are ^\\[\\d+\\]$ before calling Parse"],"exampleFix":"// before\nstrvals.Parse(\"items[-1]=x\")\n// after\nstrvals.Parse(\"items[0]=x\")","handlingStrategy":"validation","validationCode":"var negIdx = regexp.MustCompile(`\\[-\\d+\\]`)\nfunc hasNegativeIndex(setLine string) bool { return negIdx.MatchString(setLine) }","typeGuard":null,"tryCatchPattern":"if err := strvals.Parse(s); err != nil {\n    if strings.Contains(err.Error(), \"negative\") && strings.Contains(err.Error(), \"index not allowed\") { /* fix index */ }\n}","preventionTips":["Clamp computed indexes to >= 0","Compute last-element position from known length","Lint expressions for negative brackets"],"tags":["strvals","set","parsing","negative-index","helm"],"backgroundTag":null,"analyzedSha":"2a29f1770b62844b27197d2507377361d45ad7c0","analyzedAt":"2026-08-15T22:02:47.490Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}