vxcontrol/pentagi · error

invalid hunk header %q: %w

Error message

invalid hunk header %q: %w

What it means

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.

Source

Thrown at backend/pkg/tools/file_diff.go:82

		}
		i++
	}
	if i >= len(lines) {
		return nil, fmt.Errorf(`diff contains no hunks (no "@@ ... @@" header found)`)
	}

	var hunks []diffHunk
	for i < len(lines) {
		header := lines[i]
		m := unifiedDiffHunkHeaderRe.FindStringSubmatch(header)
		if m == nil {
			return nil, fmt.Errorf("invalid hunk header: %q", header)
		}
		hunk := diffHunk{header: header, oldStart: 1}
		if m[1] != "" {
			oldStart, err := strconv.Atoi(m[1])
			if err != nil {
				return nil, fmt.Errorf("invalid hunk header %q: %w", header, err)
			}
			hunk.oldStart = oldStart
			hunk.hasPosition = true
		}
		i++

		for i < len(lines) && !strings.HasPrefix(lines[i], "@@") {
			line := lines[i]
			i++

			if strings.HasPrefix(line, `\`) {
				// e.g. "\ No newline at end of file" - not a content line.
				continue
			}
			if line == "" {
				hunk.lines = append(hunk.lines, diffHunkLine{sign: ' ', text: ""})
				continue
			}

View on GitHub (pinned to ea665308ba)

Solutions

  1. Read the wrapped strconv error to see which number failed and fix it in the header.
  2. Ensure old/new start values are plain decimal integers without signs, spaces, or separators.
  3. Regenerate the diff with git diff if the header was produced programmatically with malformed values.
  4. Check for template placeholders (e.g. '{{line}}') that were never filled in.

Example fix

// before
"@@ -1,024 +1,2 @@" // leading zeros may be fine, but "@@ -1 024 +1,2 @@" fails

// after
"@@ -1024 +1,2 @@"
Defensive patterns

Strategy: validation

Validate before calling

func headerNumbersValid(header string) error {
	m := regexp.MustCompile(`^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@`).FindStringSubmatch(header)
	if m == nil { return fmt.Errorf("not a hunk header: %q", header) }
	for _, idx := range []int{1, 3, 4, 6} {
		if m[idx] != "" { if _, err := strconv.Atoi(m[idx]); err != nil { return err } }
	}
	return nil
}

Try / catch

if _, _, err := ApplyUnifiedDiff(ctx, path, diff); err != nil {
	if strings.Contains(err.Error(), "invalid hunk header") {
		// regenerate diff programmatically instead of retrying the same header
	}
	return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/391a83f04850205a. Report an issue: GitHub.