affaan-m/ECC · error

git add failed for

Error message

git add failed for {path}: {stderr}

What it means

stage_path runs `git add -- <path>` inside the worktree and, on non-zero exit, includes both the offending path and git's stderr in the error. Untracked-but-ignored paths, pathspec errors, and index lock conflicts all land here.

Solutions

  1. Check the file exists and is not gitignored before staging (`git -C <path> check-ignore <file>`; use force-add intentionally if needed)
  2. Retry after the concurrent git operation completes if stderr mentions index.lock
  3. Ensure the path is relative to the worktree root and points inside it
  4. Quote/normalize the path so it cannot be misread as a git option

Example fix

// before
stage_path(&worktree, "build/output.log")?; // ignored file
// after
if !is_ignored(&worktree, "build/output.log")? {
    stage_path(&worktree, "build/output.log")?;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check the path before staging
fn stageable(worktree: &WorktreeInfo, path: &str) -> bool {
    worktree.path.join(path).exists()
        && !Command::new("git").arg("-C").arg(&worktree.path)
            .args(["check-ignore", path]).output()
            .map(|o| o.status.success()).unwrap_or(false)
}

Try / catch

match stage_path(&worktree, path) {
    Ok(()) => (),
    Err(e) if e.to_string().contains("index.lock") => {
        wait_and_retry_stage(&worktree, path)?;
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling stage_path with a path that does not exist in the worktree, is excluded by .gitignore, matches no pathspec, or while a git index.lock is held by another process.

Common situations: Staging a file that was deleted before the call; staging a file listed in .gitignore (git add refuses without -f); two concurrent session operations racing on the same worktree index; a path with characters that confuse the pathspec (e.g. leading '-').

Understand the failure class

Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/3ccb7686a55b59ba. Report an issue: GitHub.

Appendix: source

Thrown at ecc2/src/worktree/mod.rs:304

    Ok(String::from_utf8_lossy(&output.stdout)
        .lines()
        .filter_map(parse_git_status_entry)
        .collect())
}

pub fn stage_path(worktree: &WorktreeInfo, path: &str) -> Result<()> {
    let output = Command::new("git")
        .arg("-C")
        .arg(&worktree.path)
        .args(["add", "--"])
        .arg(path)
        .output()
        .with_context(|| format!("Failed to stage {}", path))?;
    if output.status.success() {
        Ok(())
    } else {
        let stderr = String::from_utf8_lossy(&output.stderr);
        anyhow::bail!("git add failed for {path}: {stderr}");
    }
}

pub fn unstage_path(worktree: &WorktreeInfo, path: &str) -> Result<()> {
    let output = Command::new("git")
        .arg("-C")
        .arg(&worktree.path)
        .args(["reset", "HEAD", "--"])
        .arg(path)
        .output()
        .with_context(|| format!("Failed to unstage {}", path))?;
    if output.status.success() {
        Ok(())
    } else {
        let stderr = String::from_utf8_lossy(&output.stderr);
        anyhow::bail!("git reset failed for {path}: {stderr}");
    }
}

View on GitHub (pinned to 8321021c54)