{"record":{"id":"07c0d00a01a5352f","repo":"dagger/dagger","slug":"git-apply-d-file-s-could-not-be-patched-at-all","errorCode":null,"errorMessage":"git apply: %d file(s) could not be patched at all, which conflict markers cannot express:\n%s","messagePattern":"git apply: (.+?) file\\(s\\) could not be patched at all, which conflict markers cannot express:\n(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/directory.go","lineNumber":1847,"sourceCode":"\t\treturn err\n\t}\n\tconflicted := make([]string, 0, len(rejects))\n\tfor rej := range rejects {\n\t\tif !preexisting[rej] {\n\t\t\tconflicted = append(conflicted, rej)\n\t\t}\n\t}\n\tif runErr != nil {\n\t\t// --reject reports a hunk it could not place and a file it could not\n\t\t// patch at all with the same exit status, but only the former leaves\n\t\t// a .rej behind. The latter — creating a file that already exists,\n\t\t// editing one that is gone, a binary diff without full index lines —\n\t\t// is skipped outright, leaving nothing in the tree to show that the\n\t\t// change was dropped. The markers below cannot express that, so it\n\t\t// stays a failure rather than passing for a conflict whenever some\n\t\t// other hunk happened to be rejected as well.\n\t\tif failed := wholeFileApplyErrors(stderr.String()); len(failed) > 0 {\n\t\t\treturn fmt.Errorf(\"git apply: %d file(s) could not be patched at all, which conflict markers cannot express:\\n%s\",\n\t\t\t\tlen(failed), strings.Join(failed, \"\\n\"))\n\t\t}\n\t\tif len(conflicted) == 0 {\n\t\t\t// No rejects written: a hard failure (bad patch, not a content\n\t\t\t// conflict).\n\t\t\treturn fmt.Errorf(\"git apply: %w\", runErr)\n\t\t}\n\t}\n\tif len(conflicted) == 0 {\n\t\treturn nil\n\t}\n\tsort.Strings(conflicted)\n\tconflictedTargets := make([]string, 0, len(conflicted))\n\tfor _, rej := range conflicted {\n\t\ttarget := strings.TrimSuffix(rej, \".rej\")\n\t\tif err := convertRejectToMarkers(filepath.Join(dir, target), filepath.Join(dir, rej)); err != nil {\n\t\t\treturn fmt.Errorf(\"convert %s to conflict markers: %w\", rej, err)\n\t\t}","sourceCodeStart":1829,"sourceCodeEnd":1865,"githubUrl":"https://github.com/dagger/dagger/blob/82ba2681dbe30d3547a1dc50ea495900ab5b6047/core/directory.go#L1829-L1865","documentation":"When leaveMarkers is enabled, Dagger can convert per-file rejects into conflict markers, but some failures — a file missing entirely, a binary diff without full index lines — are skipped outright by git apply with nothing written to the tree. Because markers cannot express a wholly-unpatched file, Dagger fails hard listing the files found via wholeFileApplyErrors in stderr.","triggerScenarios":"Applying a patch (with conflict-marker mode enabled) where git apply reports whole-file failures: the target file does not exist (created/deleted diffs), binary diffs lacking index blobs, or diffs whose paths never resolve inside the directory.","commonSituations":"Rebase-flavored workflows patching files that were renamed or deleted upstream; patches carrying binary assets without the full binary index; patches produced from a different tree layout than the target directory.","solutions":["Read the listed file names in the error and check whether each exists in the target directory","Regenerate the patch (including binary index data: git diff --binary) against the target's current state","For intentionally-absent files, remove them from the patch or restructure the change into per-file patches that apply cleanly","Resolve the drift between the patch base and directory contents before applying, e.g. by patching the original base and re-copying"],"exampleFix":"// before\ngit diff > fix.patch  // binary asset added, no --binary flag\n// after\ngit diff --binary > fix.patch // full index lines so git apply can apply binary files","handlingStrategy":"validation","validationCode":"// ensure every path the diff touches exists and no binary diffs lack index data\nfor (const f of diff.filesTouched()) {\n  try { await target.file(f).size() } catch { throw new Error(`patched file missing: ${f}`) }\n}\n// generate patches with: git diff --binary","typeGuard":null,"tryCatchPattern":"try {\n  await target.patch(patchFile)\n} catch (e) {\n  if (String(e).includes('could not be patched at all')) {\n    const files = String(e).split('\\n').slice(1) // list after the header\n    throw new Error(`unpatchable files, regenerate diff --binary for: ${files.join(', ')}`)\n  }\n  throw e\n}","preventionTips":["Always generate diffs with git diff --binary when binary files are involved","Regenerate patches after any upstream rename/delete of touched files","Keep the patch base and target directory in sync (rebase before patching)"],"tags":["git","patch","git-apply","conflict","binary"],"backgroundTag":"git-apply-failed","analyzedSha":"82ba2681dbe30d3547a1dc50ea495900ab5b6047","analyzedAt":"2026-09-05T07:21:37.930Z","contentChangedAt":"2026-09-05T07:21:37.930Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}