{"record":{"id":"391a83f04850205a","repo":"vxcontrol/pentagi","slug":"invalid-hunk-header-q-w","errorCode":null,"errorMessage":"invalid hunk header %q: %w","messagePattern":"invalid hunk header %q: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/tools/file_diff.go","lineNumber":82,"sourceCode":"\t\t}\n\t\ti++\n\t}\n\tif i >= len(lines) {\n\t\treturn nil, fmt.Errorf(`diff contains no hunks (no \"@@ ... @@\" header found)`)\n\t}\n\n\tvar hunks []diffHunk\n\tfor i < len(lines) {\n\t\theader := lines[i]\n\t\tm := unifiedDiffHunkHeaderRe.FindStringSubmatch(header)\n\t\tif m == nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid hunk header: %q\", header)\n\t\t}\n\t\thunk := diffHunk{header: header, oldStart: 1}\n\t\tif m[1] != \"\" {\n\t\t\toldStart, err := strconv.Atoi(m[1])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid hunk header %q: %w\", header, err)\n\t\t\t}\n\t\t\thunk.oldStart = oldStart\n\t\t\thunk.hasPosition = true\n\t\t}\n\t\ti++\n\n\t\tfor i < len(lines) && !strings.HasPrefix(lines[i], \"@@\") {\n\t\t\tline := lines[i]\n\t\t\ti++\n\n\t\t\tif strings.HasPrefix(line, `\\`) {\n\t\t\t\t// e.g. \"\\ No newline at end of file\" - not a content line.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif line == \"\" {\n\t\t\t\thunk.lines = append(hunk.lines, diffHunkLine{sign: ' ', text: \"\"})\n\t\t\t\tcontinue\n\t\t\t}","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/tools/file_diff.go#L64-L100","documentation":"Same regex family as the previous error, but the header matched '@@ ... @@' while the old-start line number is not a valid integer (strconv.Atoi failed). This variant wraps the underlying strconv error, so the message includes both the header and the numeric parse failure.","triggerScenarios":"Hunk headers like '@@ -1e3,2 +1,2 @@' or '@@ -+1,2 +1,2 @@' where the oldStart field passes the regex's numeric-ish shape but overflows int or contains invalid characters.","commonSituations":"Diffs generated for very large files where line counts exceed int range on the platform; corrupted diffs from network transfer; templated diffs where a variable failed to substitute leaving placeholder text.","solutions":["Read the wrapped strconv error to see which number failed and fix it in the header.","Ensure old/new start values are plain decimal integers without signs, spaces, or separators.","Regenerate the diff with git diff if the header was produced programmatically with malformed values.","Check for template placeholders (e.g. '{{line}}') that were never filled in."],"exampleFix":"// before\n\"@@ -1,024 +1,2 @@\" // leading zeros may be fine, but \"@@ -1 024 +1,2 @@\" fails\n\n// after\n\"@@ -1024 +1,2 @@\"","handlingStrategy":"validation","validationCode":"func headerNumbersValid(header string) error {\n\tm := regexp.MustCompile(`^@@ -(\\d+)(,(\\d+))? \\+(\\d+)(,(\\d+))? @@`).FindStringSubmatch(header)\n\tif m == nil { return fmt.Errorf(\"not a hunk header: %q\", header) }\n\tfor _, idx := range []int{1, 3, 4, 6} {\n\t\tif m[idx] != \"\" { if _, err := strconv.Atoi(m[idx]); err != nil { return err } }\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"if _, _, err := ApplyUnifiedDiff(ctx, path, diff); err != nil {\n\tif strings.Contains(err.Error(), \"invalid hunk header\") {\n\t\t// regenerate diff programmatically instead of retrying the same header\n\t}\n\treturn err\n}","preventionTips":["Generate line numbers from actual file offsets, never from templates or guesses","Check for unfilled template placeholders in generated headers","Guard against integer overflow when diffing extremely large files"],"tags":["diff","parsing","strconv","unified-diff"],"backgroundTag":"invalid-hunk-header","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}