{"record":{"id":"58d2aefbc6669295","repo":"vxcontrol/pentagi","slug":"d-of-d-hunk-s-could-not-be-applied-read-the-f","errorCode":null,"errorMessage":"%d of %d hunk(s) could not be applied - read the file again and retry with context that matches its current content exactly:\n%s","messagePattern":"(.+?) of (.+?) hunk\\(s\\) could not be applied - read the file again and retry with context that matches its current content exactly:\n(.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/tools/file_diff.go","lineNumber":315,"sourceCode":"\n\tpatchText := buildGoDiffPatchText(hunks, content)\n\n\tdmp := diffmatchpatch.New()\n\tpatches, err := dmp.PatchFromText(patchText)\n\tif err != nil {\n\t\treturn \"\", 0, fmt.Errorf(\"internal error building patch: %w\", err)\n\t}\n\n\tnewContent, applied := dmp.PatchApply(patches, content)\n\n\tvar failed []string\n\tfor i, ok := range applied {\n\t\tif !ok && i < len(hunks) {\n\t\t\tfailed = append(failed, fmt.Sprintf(\"%s (not found in the file, looked for: %q)\", hunks[i].header, hunkOldPreview(hunks[i])))\n\t\t}\n\t}\n\tif len(failed) > 0 {\n\t\treturn \"\", 0, fmt.Errorf(\n\t\t\t\"%d of %d hunk(s) could not be applied - read the file again and retry with context that matches its current content exactly:\\n%s\",\n\t\t\tlen(failed), len(hunks), strings.Join(failed, \"\\n\"),\n\t\t)\n\t}\n\n\treturn newContent, len(hunks), nil\n}\n","sourceCodeStart":297,"sourceCodeEnd":323,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/tools/file_diff.go#L297-L323","documentation":"diff-match-patch applied the patch, but one or more hunks did not find their context in the current file content. The error lists which hunk headers failed and a preview of the text each hunk expected to find, instructing the caller to re-read the file and retry with exact context. This is the expected failure mode for diffs built against a stale version of the file.","triggerScenarios":"EditFile/ApplyUnifiedDiff called with a diff whose context lines do not byte-match the file's current content — file changed since the diff was made, line numbers drifted, trailing whitespace or line endings differ, or context was paraphrased by an LLM instead of copied.","commonSituations":"Concurrent edits between reading the file and applying the diff; agent generated context from memory rather than an actual file read; CRLF vs LF mismatch; context lines abbreviated with '...' or re-wrapped by chat rendering.","solutions":["Re-read the file from disk and regenerate the diff using its current exact content as context.","Copy context lines verbatim from the file, including trailing whitespace, instead of retyping them.","Reduce the amount of context to the minimum needed to be unique, lessening the chance of mismatch.","Normalize line endings (match the file's CRLF/LF convention) before applying.","Retry after confirming no other process is concurrently modifying the file."],"exampleFix":"// before: context invented by the model\n\"@@ -3,2 +3,3 @@\\n some old line\\n+added\"\n\n// after: context copied exactly from a fresh file read\n\"@@ -3,2 +3,3 @@\\n someOldLine := compute(x) // exact current line\\n+added\"","handlingStrategy":"retry","validationCode":"func contextMatches(content, ctxLine string) bool {\n\treturn strings.Contains(content, strings.TrimPrefix(ctxLine, \" \"))\n}\n// verify every context/removal line appears in freshly read content before applying","typeGuard":null,"tryCatchPattern":"for attempt := 0; attempt < 3; attempt++ {\n\tcontent, _ := readFile(path) // fresh read each attempt\n\tdiff := buildDiffAgainst(content)\n\tnewContent, _, err := ApplyUnifiedDiff(ctx, path, diff)\n\tif err == nil { return newContent, nil }\n\tif !strings.Contains(err.Error(), \"could not be applied\") { return err }\n}","preventionTips":["Always build diffs from a file read in the same session — never from cached or remembered content","Copy context lines verbatim including trailing whitespace","Minimize context lines to what is needed for uniqueness","Match the file's line-ending convention (CRLF vs LF)","Avoid concurrent writers to the same file while diffing"],"tags":["diff","patch-apply","stale-content","conflict"],"backgroundTag":"diff-apply-context-mismatch","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}