affaan-m/ECC · error
git apply failed while trying to {action}: {stderr}
Error message
git apply failed while trying to {action}: {stderr} What it means
Thrown by git_apply_patch at ecc2/src/worktree/mod.rs:1198 when a `git -C <worktree_path> apply <args>` child process (fed the patch via stdin) exits non-zero. The `action` string parameter is interpolated so the error names what the apply was attempting (e.g. 'sync node_modules', 'restore staged hunk'). Stdout is redirected to null and stderr is captured, so only the stderr channel is reported.
Source
Thrown at ecc2/src/worktree/mod.rs:1198
{
let stdin = child
.stdin
.as_mut()
.context("Failed to open git apply stdin")?;
stdin
.write_all(patch.as_bytes())
.with_context(|| format!("Failed to write patch for {action}"))?;
}
let output = child
.wait_with_output()
.with_context(|| format!("Failed to wait for git apply while trying to {action}"))?;
if output.status.success() {
Ok(())
} else {
let stderr = String::from_utf8_lossy(&output.stderr);
anyhow::bail!("git apply failed while trying to {action}: {stderr}");
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
struct SharedDependencyStrategy {
label: &'static str,
dir_name: &'static str,
fingerprint_files: Vec<&'static str>,
}
fn sync_shared_dependency_dirs_in_repo(
worktree: &WorktreeInfo,
repo_root: &Path,
) -> Result<Vec<String>> {
let mut applied = Vec::new();
for strategy in detect_shared_dependency_strategies(repo_root) {
if sync_shared_dependency_dir(worktree, repo_root, &strategy)? {
applied.push(strategy.label.to_string());View on GitHub (pinned to 01e15490f0)
Solutions
- Regenerate the patch from the worktree's current state before applying (the context lines must match).
- Apply with --3way for content reconciliation: pass `--3way` in args so git falls back to merge resolution instead of failing on context mismatch.
- Verify the patch was generated with matching path prefixes (use `git apply --p=<n>` or `--directory=<dir>` to align).
- Discard the half-applied state with `git -C <worktree_path> checkout -- .` and re-attempt from a clean tree.
Example fix
// before
let args = ["--index"];
git_apply_patch(&wt.path, &args, &patch, "stage hunk")?;
// after: retry with 3-way merge on context mismatch
let args = ["--index"];
if let Err(e) = git_apply_patch(&wt.path, &args, &patch, "stage hunk") {
tracing::warn!("plain apply failed ({e}); retrying with --3way");
let args3 = ["--index", "--3way"];
git_apply_patch(&wt.path, &args3, &patch, "stage hunk")?;
} Defensive patterns
Strategy: retry
Validate before calling
// Dry-run the patch before committing to it
fn patch_applies_cleanly(worktree_path: &Path, args: &[&str], patch: &str) -> bool {
let mut cmd = Command::new("git");
cmd.arg("-C").arg(worktree_path).arg("apply").arg("--check").args(args)
.stdin(Stdio::piped()).stdout(Stdio::null()).stderr(Stdio::null());
if let Ok(mut child) = cmd.spawn() {
if let Some(stdin) = child.stdin.as_mut() { let _ = stdin.write_all(patch.as_bytes()); }
child.wait().map(|s| s.success()).unwrap_or(false)
} else { false }
}
if !patch_applies_cleanly(&wt.path, &args, &patch) {
anyhow::bail!("patch context no longer matches; regenerate it");
} Type guard
null
Try / catch
match git_apply_patch(&wt.path, &args, &patch, action) {
Ok(()) => (),
Err(e) if e.to_string().starts_with("git apply failed") => {
// retry with 3-way merge so git reconciles context
let args3: Vec<&str> = args.iter().chain([&"--3way"]).copied().collect();
git_apply_patch(&wt.path, &args3, &patch, action)?;
}
Err(e) => return Err(e),
} Prevention
- Generate the patch immediately before applying it; stale patches are the usual cause.
- Always pass --3way for shared-dependency sync patches where context drifts.
- Ensure line-ending settings (.gitattributes / core.autocrlf) match between generation and application.
- Validate path prefixes between patch generation and apply (use --directory or --p=N when they differ).
When it happens
Trigger: Applying a patch whose context lines no longer match the worktree's current content; applying a patch generated with different --line-prefix or whitespace settings; applying a patch to files that were modified or deleted since the patch was generated; `git apply --check` semantics where a hunk fails to apply cleanly; partial apply (3-way merge disabled) leaving the worktree half-patched.
Common situations: Syncing shared dependency dirs (node_modules, target/, venv) when the worktree's source files diverged from the fingerprint; restoring staged hunks after a concurrent edit; applying a patch across line-ending conversions (CRLF vs LF); path prefix mismatch when the patch was generated from repo root but applied in a sub-worktree.
Related errors
- git merge failed: {stderr}
- git rebase failed: {}{}
- Merge blocked between {left_branch} and {right_branch} by {}
- git diff failed: {stderr}
- git worktree list --porcelain failed: {stderr}
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/0de19fa2c3360850.
Report an issue: GitHub.