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

  1. Regenerate the patch from the worktree's current state before applying (the context lines must match).
  2. Apply with --3way for content reconciliation: pass `--3way` in args so git falls back to merge resolution instead of failing on context mismatch.
  3. Verify the patch was generated with matching path prefixes (use `git apply --p=<n>` or `--directory=<dir>` to align).
  4. 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

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


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/0de19fa2c3360850. Report an issue: GitHub.