Hmbown/CodeWhale · error
Failed to run git apply
Error message
Failed to run git apply: {e} What it means
Raised when the `git apply` subprocess itself fails to launch — `cmd.output()` returns an io::Error (distinct from git running but exiting non-zero, which produces 'git apply failed: <stderr>'). The patch was already written to a temp file at this point; only process startup failed.
Solutions
- Retry the apply; transient fork failures often clear under reduced load
- Check container/fd/pid limits (ulimit, cgroup pids.max) if failures are repeated
- Confirm git remains on PATH and executable for the whole session
- Verify the temp directory (TMPDIR) is writable and accessible to git
Example fix
// before
.output()
.map_err(|e| anyhow::anyhow!("Failed to run git apply: {e}"))?;
// after
.output()
.map_err(|e| anyhow::anyhow!("Failed to run git apply: {e} (check git is installed and TMPDIR '{}' is accessible)", std::env::temp_dir().display()))?; Defensive patterns
Strategy: try-catch
Validate before calling
// Rust
if which::which("git").is_err() {
bail!("git must be on PATH before running apply");
}
assert!(tmp_path.exists(), "temp patch file missing before git apply"); Try / catch
// Rust
let output = cmd.output()
.map_err(|e| anyhow::anyhow!("Failed to run git apply: {e}"))?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();
bail!("git apply failed: {stderr}");
} Prevention
- Check fd/pid limits in containers that spawn many subprocesses
- Keep TMPDIR writable and accessible to child processes
- Retry transient spawn failures once before failing the operation
- Log stderr of git apply so patch conflicts are diagnosable
When it happens
Trigger: `.output()` errors while spawning `git apply --whitespace=nowarn <tmpfile>` — git disappeared from PATH between check and spawn, exec permission lost, tmpfile path invalid for exec context, or fork/resource exhaustion.
Common situations: Race where the environment changes mid-run; SELinux/AppArmor blocking exec; out-of-memory or PID limits in containers preventing fork; temp file on a mount invisible to the spawned git process.
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
- Failed to run git diff. Is git installed?
- git apply failed
- git failed
- git not found
- A full Git history is required to establish the PR merge…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/c969cf1b45fa1494.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/lib.rs:9921
.map_err(|e| anyhow::anyhow!("Failed to read patch {}: {}", path.display(), e))?
} else {
read_patch_from_stdin()?
};
if patch.trim().is_empty() {
bail!("Patch is empty.");
}
let mut tmp = NamedTempFile::new()?;
tmp.write_all(patch.as_bytes())?;
let tmp_path = tmp.path().to_path_buf();
let output = crate::dependencies::Git::command()
.ok_or_else(|| anyhow::anyhow!("git not found on PATH"))?
.arg("apply")
.arg("--whitespace=nowarn")
.arg(&tmp_path)
.output()
.map_err(|e| anyhow::anyhow!("Failed to run git apply: {e}"))?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
bail!("git apply failed: {}", stderr.trim());
}
println!("Applied patch successfully.");
Ok(())
}
/// Maximum bytes read for a patch on stdin. Generous for large diffs;
/// anything larger is not a patch.
const MAX_STDIN_PATCH_BYTES: u64 = 16 * 1024 * 1024;
fn read_patch_from_stdin() -> Result<String> {
let stdin = io::stdin();
if stdin.is_terminal() {
bail!("No patch file provided and stdin is empty.");
}View on GitHub (pinned to 73e0f67d83)