{"record":{"id":"8bf57d5964b4d841","repo":"nikivdev/code","slug":"git-add-failed-with","errorCode":null,"errorMessage":"git add failed with {}","messagePattern":"git add failed with (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/codex_session_docs.rs","lineNumber":1509,"sourceCode":"    paths.push(display_repo_relative(\n        &project_root.display().to_string(),\n        &promotion_path_for_session_json(Path::new(&entry.session_json_path))\n            .display()\n            .to_string(),\n    ));\n    dedupe_preserve_order(paths)\n}\n\nfn git_add_paths(project_root: &Path, paths: &[String]) -> Result<()> {\n    let status = Command::new(\"git\")\n        .current_dir(project_root)\n        .arg(\"add\")\n        .arg(\"--\")\n        .args(paths)\n        .status()\n        .context(\"failed to run git add\")?;\n    if !status.success() {\n        bail!(\"git add failed with {}\", status);\n    }\n    Ok(())\n}\n\nfn git_commit_paths(project_root: &Path, message: &str) -> Result<()> {\n    let status = Command::new(\"git\")\n        .current_dir(project_root)\n        .args([\"commit\", \"-m\", message])\n        .status()\n        .context(\"failed to run git commit\")?;\n    if !status.success() {\n        bail!(\"git commit failed with {}\", status);\n    }\n    Ok(())\n}\n\nfn build_doc_commit_message(\n    entries: &[DocReviewQueueEntry],","sourceCodeStart":1491,"sourceCodeEnd":1527,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/codex_session_docs.rs#L1491-L1527","documentation":"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.","triggerScenarios":"`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.","commonSituations":"Read-only checkout; concurrent git operations holding `.git/index.lock`; paths containing characters your git version mishandles; detached/bare repo states blocking index writes.","solutions":["Run `git add -- <paths>` manually to see the underlying git error","Remove a stale `.git/index.lock` if present and retry","Ensure the repository is writable by the user running the tool"],"exampleFix":"// before\nlet status = cmd.status().context(\"failed to run git add\")?;\nif !status.success() { bail!(\"git add failed with {}\", status); }\n// after\nif !status.success() {\n    let err = String::from_utf8_lossy(&output.stderr);\n    bail!(\"git add failed with {}: {}\", status, err.trim());\n}","handlingStrategy":"retry","validationCode":"anyhow::ensure!(!Path::new(\".git/index.lock\").exists(), \"git index locked; wait or remove stale lock\");\nanyhow::ensure!(writable(root), \"repo must be writable to stage files\");","typeGuard":"fn can_stage(root: &Path) -> bool {\n    root.join(\".git\").exists() && !root.join(\".git/index.lock\").exists()\n}","tryCatchPattern":"for attempt in 0..3 {\n    match git_add_paths(root, &paths) {\n        Ok(()) => break,\n        Err(e) if e.to_string().contains(\"git add failed\") && attempt < 2 => {\n            std::thread::sleep(Duration::from_millis(250 * (attempt + 1)));\n        }\n        Err(e) => return Err(e),\n    }\n}","preventionTips":["Avoid running concurrent git operations on the same checkout","Ensure the tool's user owns or can write the repository","Retry transient failures after clearing stale index locks"],"tags":["git","subprocess","staging"],"backgroundTag":"git-command-failed","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}