vxcontrol/pentagi · error
diff contains no hunks (no "@@ ... @@" header found)
Error message
diff contains no hunks (no "@@ ... @@" header found)
What it means
parseUnifiedDiff in backend/pkg/tools/file_diff.go scans a unified diff for the first '@@ ... @@' hunk header. If it consumes the entire input without finding one, it reports that the diff contains no hunks. The tool requires a well-formed unified diff; input like 'old file text' or a plain English description of the edit is not accepted.
Source
Thrown at backend/pkg/tools/file_diff.go:68
// separate argument), "\ No newline at end of file" markers, and a fully
// blank line standing in for a one-space (empty) context line.
func parseUnifiedDiff(diffText string) ([]diffHunk, error) {
normalized := strings.TrimSuffix(strings.ReplaceAll(diffText, "\r\n", "\n"), "\n")
if normalized == "" {
return nil, fmt.Errorf("diff is empty")
}
lines := strings.Split(normalized, "\n")
i := 0
for i < len(lines) && !strings.HasPrefix(lines[i], "@@") {
trimmed := strings.TrimSpace(lines[i])
if trimmed != "" && !strings.HasPrefix(trimmed, "---") && !strings.HasPrefix(trimmed, "+++") {
return nil, fmt.Errorf("expected a hunk header (\"@@ -old +new @@\") but found: %q", lines[i])
}
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
}View on GitHub (pinned to ea665308ba)
Solutions
- Inspect the diff string passed to ApplyUnifiedDiff and ensure it contains at least one '@@ -old +new @@' hunk header after the optional ---/+++ file headers.
- If the diff is produced by another tool or LLM, ask it to regenerate as a proper unified diff (git diff format) with hunk headers.
- Check the input is not empty or truncated (log its length and first lines before calling ApplyUnifiedDiff).
- If no change is actually needed, skip calling ApplyUnifiedDiff entirely instead of passing an empty diff.
Example fix
// before ApplyUnifiedDiff(ctx, path, "--- a/f.txt\n+++ b/f.txt") // after ApplyUnifiedDiff(ctx, path, "--- a/f.txt\n+++ b/f.txt\n@@ -1,1 +1,2 @@\n old line\n+new line")
Defensive patterns
Strategy: validation
Validate before calling
func hasHunkHeader(diff string) bool {
return strings.Contains(diff, "@@") && regexp.MustCompile(`(?m)^@@ -\d+(,\d+)? \+\d+(,\d+)? @@`).MatchString(diff)
}
// call ApplyUnifiedDiff only if hasHunkHeader(diff) && strings.TrimSpace(diff) != "" Try / catch
newContent, n, err := ApplyUnifiedDiff(ctx, path, diff)
if err != nil {
if strings.Contains(err.Error(), "no hunks") {
// treat as no-op or regenerate a proper unified diff
}
return err
} Prevention
- Always generate diffs with a real tool (git diff -U3) instead of hand-writing them
- Log the first lines of the diff before applying to catch empty/truncated input early
- Reject empty diffs at the call site instead of passing them to the applier
- In LLM pipelines, include a unified-diff format example in the prompt/schema
When it happens
Trigger: ApplyUnifiedDiff or EditFile called with a diff string that has no '@@ -a,b +c,d @@' header at all — e.g. an empty string, a natural-language description of the change, plain search/replace text, or a header-only diff whose lines after ---/+++ are not hunk headers.
Common situations: An LLM agent returns a prose description or a '```diff' block that is actually empty; user pastes only the file-portion (---/+++) of a git diff; a template generated an empty diff when content was unchanged; diff output got truncated before the first hunk.
Related errors
- invalid hunk header: %q
- invalid hunk header %q: %w
- invalid diff line (must start with ' ', '-', or '+'): %q
- hunk %q has no content lines
- failed to apply diff to %s: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/478584be8d396de1.
Report an issue: GitHub.