{"record":{"id":"ce8b3dbdf3c0ea33","repo":"helm/helm","slug":"file-does-not-exist","errorCode":null,"errorMessage":"file does not exist","messagePattern":"file does not exist","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/chart/v3/lint/rules/values.go","lineNumber":51,"sourceCode":"// they are only tested for well-formedness.\n//\n// If additional values are supplied, they are coalesced into the values in values.yaml.\nfunc ValuesWithOverrides(linter *support.Linter, valueOverrides map[string]any, skipSchemaValidation bool) {\n\tfile := \"values.yaml\"\n\tvf := filepath.Join(linter.ChartDir, file)\n\tfileExists := linter.RunLinterRule(support.InfoSev, file, validateValuesFileExistence(vf))\n\n\tif !fileExists {\n\t\treturn\n\t}\n\n\tlinter.RunLinterRule(support.ErrorSev, file, validateValuesFile(vf, valueOverrides, skipSchemaValidation))\n}\n\nfunc validateValuesFileExistence(valuesPath string) error {\n\t_, err := os.Stat(valuesPath)\n\tif err != nil {\n\t\treturn errors.New(\"file does not exist\")\n\t}\n\treturn nil\n}\n\nfunc validateValuesFile(valuesPath string, overrides map[string]any, skipSchemaValidation bool) error {\n\tvalues, err := common.ReadValuesFile(valuesPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to parse YAML: %w\", err)\n\t}\n\n\t// Helm 3.0.0 carried over the values linting from Helm 2.x, which only tests the top\n\t// level values against the top-level expectations. Subchart values are not linted.\n\t// We could change that. For now, though, we retain that strategy, and thus can\n\t// coalesce tables (like reuse-values does) instead of doing the full chart\n\t// CoalesceValues\n\tcoalescedValues := util.CoalesceTables(make(map[string]any, len(overrides)), overrides)\n\tcoalescedValues = util.CoalesceTables(coalescedValues, values)\n","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/helm/helm/blob/2a29f1770b62844b27197d2507377361d45ad7c0/internal/chart/v3/lint/rules/values.go#L33-L69","documentation":"parser.listItem (pkg/strvals/parser.go:335) rejects negative list indexes while processing the main --set/--set-json grammar. keyIndex() parses the bracket text with strconv.Atoi, which accepts '-1'; listItem then refuses it before touching the list. This is the error users actually see for 'a[-1]=v' in --set.","triggerScenarios":"strvals.Parse(\"a[-1]=v\"), strvals.ParseJSON(\"a[-1]=null\", dest), nested variants like \"a.b[-1]=v\".","commonSituations":"Python/Ruby-style negative indexing habits; loop counters or env interpolation that evaluate to a negative number; migrating scripts from tools that allow -1 as last element.","solutions":["Replace negative indexes with explicit non-negative 0-based ones","Compute the real index from the list length before building the expression","Sanitize generated expressions: reject any \\[-\\d+\\] bracket"],"exampleFix":"# before\nhelm install mychart --set hosts[-1]=example.com\n# after\nhelm install mychart --set hosts[0]=example.com","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 && strings.Contains(err.Error(), \"index not allowed\") {\n    return fmt.Errorf(\"negative list index unsupported: %w\", err)\n}","preventionTips":["--set has no count-from-end indexing","Validate interpolated indexes are non-negative integers","Compute real positions before building expressions"],"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"}