nikivdev/code · error

git add failed with {}

Error message

git add failed with {}

What it means

Staging files for the doc commit via `git add -- <paths>` failed with a non-zero exit status, which the library converts into this error. The context line "failed to run git add" distinguishes spawn failures from this exit-status failure.

Source

Thrown at src/codex_session_docs.rs:1509

    paths.push(display_repo_relative(
        &project_root.display().to_string(),
        &promotion_path_for_session_json(Path::new(&entry.session_json_path))
            .display()
            .to_string(),
    ));
    dedupe_preserve_order(paths)
}

fn git_add_paths(project_root: &Path, paths: &[String]) -> Result<()> {
    let status = Command::new("git")
        .current_dir(project_root)
        .arg("add")
        .arg("--")
        .args(paths)
        .status()
        .context("failed to run git add")?;
    if !status.success() {
        bail!("git add failed with {}", status);
    }
    Ok(())
}

fn git_commit_paths(project_root: &Path, message: &str) -> Result<()> {
    let status = Command::new("git")
        .current_dir(project_root)
        .args(["commit", "-m", message])
        .status()
        .context("failed to run git commit")?;
    if !status.success() {
        bail!("git commit failed with {}", status);
    }
    Ok(())
}

fn build_doc_commit_message(
    entries: &[DocReviewQueueEntry],

View on GitHub (pinned to a747e741ae)

Solutions

  1. Run `git add -- <paths>` manually to see the underlying git error
  2. Remove a stale `.git/index.lock` if present and retry
  3. Ensure the repository is writable by the user running the tool

Example fix

// before
let status = cmd.status().context("failed to run git add")?;
if !status.success() { bail!("git add failed with {}", status); }
// after
if !status.success() {
    let err = String::from_utf8_lossy(&output.stderr);
    bail!("git add failed with {}: {}", status, err.trim());
}
Defensive patterns

Strategy: retry

Validate before calling

anyhow::ensure!(!Path::new(".git/index.lock").exists(), "git index locked; wait or remove stale lock");
anyhow::ensure!(writable(root), "repo must be writable to stage files");

Type guard

fn can_stage(root: &Path) -> bool {
    root.join(".git").exists() && !root.join(".git/index.lock").exists()
}

Try / catch

for attempt in 0..3 {
    match git_add_paths(root, &paths) {
        Ok(()) => break,
        Err(e) if e.to_string().contains("git add failed") && attempt < 2 => {
            std::thread::sleep(Duration::from_millis(250 * (attempt + 1)));
        }
        Err(e) => return Err(e),
    }
}

Prevention

When it happens

Trigger: `git add` failing while staging the enumerated changed paths — commonly due to pathspec errors, permission problems, index lock, or files changed by another process between status and add.

Common situations: Read-only checkout; concurrent git operations holding `.git/index.lock`; paths containing characters your git version mishandles; detached/bare repo states blocking index writes.

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 nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/8bf57d5964b4d841. Report an issue: GitHub.