dagger/dagger · error
parse hunk header %q: %w
Error message
parse hunk header %q: %w
What it means
When parsing a .rej (reject) file produced by `git apply`, each hunk header (e.g. `@@ -12,7 +12,8 @@`) is matched with rejectHunkHeader and its old start line parsed with strconv.Atoi. This error wraps a non-numeric or unexpected hunk-header line number.
Source
Thrown at core/directory.go:1958
// convertRejectToMarkers folds a git-apply .rej file into its target as
// git-style conflict markers: the surrounding content is left in place (the
// "workspace" side) and each rejected hunk's intended result is inserted at
// its recorded pre-image position (the "patch" side). Best-effort placement:
// the content has drifted from what the hunk expected — that is why it was
// rejected — so the markers flag the intent for a human or agent to resolve
// rather than reproduce the edit exactly.
func convertRejectToMarkers(targetPath, rejPath string) error {
rejBytes, err := os.ReadFile(rejPath)
if err != nil {
return err
}
var hunks []rejectHunk
for _, line := range strings.Split(string(rejBytes), "\n") {
if m := rejectHunkHeader.FindStringSubmatch(line); m != nil {
oldStart, err := strconv.Atoi(m[1])
if err != nil {
return fmt.Errorf("parse hunk header %q: %w", line, err)
}
hunks = append(hunks, rejectHunk{oldStart: oldStart})
continue
}
if len(hunks) == 0 {
continue // file header
}
h := &hunks[len(hunks)-1]
if strings.HasPrefix(line, " ") || strings.HasPrefix(line, "+") {
h.theirs = append(h.theirs, line[1:])
}
}
if len(hunks) == 0 {
return nil
}
var lines []string
trailingNewline := trueView on GitHub (pinned to 82ba2681db)
Solutions
- Open the .rej/.patch file and correct the malformed @@ hunk header so the old start line is an integer.
- Regenerate the patch/diff with `git diff` or `git apply` to replace the corrupted file.
- If the .rej came from your own tooling, fix the generator to emit standard unified-diff headers.
- Apply the rejected hunks manually and commit, bypassing automatic conflict-marker conversion.
Example fix
// before (malformed hunk header) @@ -a,7 +b,8 @@ // after @@ -12,7 +12,8 @@
Defensive patterns
Strategy: validation
Validate before calling
// validate hunk headers are well-formed before processing
const hunkRe = /^@@ -(\d+)(?:,\d+)? \+\d+(?:,\d+)? @@/;
for (const line of rejText.split("\n")) {
if (line.startsWith("@@") && !hunkRe.test(line)) {
throw new Error(`malformed hunk header: ${line}`);
}
} Type guard
function isWellFormedHunkHeader(line) {
const m = /^@@ -(\d+)(?:,\d+)? \+\d+(?:,\d+)? @@/.exec(line);
return m !== null && Number.isInteger(parseInt(m[1], 10));
} Try / catch
try {
dir.patch(diff)
} catch (err) {
if (String(err).includes("parse hunk header")) {
// regenerate the patch programmatically
diff = regenerateDiff(baseDir, targetDir)
} else throw err
} Prevention
- Never hand-edit @@ hunk headers.
- Regenerate patches with `git diff` instead of fixing them manually.
- Validate generated patches with `git apply --check` before storage.
- Watch for tools that rewrite diff files (editors, formatters) corrupting headers.
When it happens
Trigger: A malformed or hand-edited .rej/.patch whose hunk header looks like a match to rejectHunkHeader but whose line-number group is not a plain integer (e.g. `@@ -a,3 +b,4 @@`), or a regex false-positive on an unusual line.
Common situations: Patches edited by hand or by tooling that corrupted the @@ header; patches with nonstandard formats (unified diff variants); .rej files truncated or concatenated from multiple patches.
Related errors
- failed to generate patch: %w
- changeset declared file changes %v but materialized no diff
- applied content for %q did not land in the merge worktree
- compare delta files: %w
- git apply: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/1e7a11918c5f3db1.
Report an issue: GitHub.