affaan-m/ECC · error · anyhow::Error
git worktree add failed: {stderr}
Error message
git worktree add failed: {stderr} What it means
The worktree creator runs `git -C <repo> worktree add -b <branch> <path> HEAD` and it exited non-zero. The full git stderr is interpolated into the message, so the precise git-level cause is in {stderr}.
Source
Thrown at ecc2/src/worktree/mod.rs:126
// Get current branch as base
let base = get_current_branch(repo_root)?;
std::fs::create_dir_all(&cfg.worktree_root)
.context("Failed to create worktree root directory")?;
let output = Command::new("git")
.arg("-C")
.arg(repo_root)
.args(["worktree", "add", "-b", &branch])
.arg(&path)
.arg("HEAD")
.output()
.context("Failed to run git worktree add")?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
anyhow::bail!("git worktree add failed: {stderr}");
}
tracing::info!(
"Created worktree at {} on branch {}",
path.display(),
branch
);
let info = WorktreeInfo {
path,
branch,
base_branch: base,
};
if let Err(error) = sync_shared_dependency_dirs_in_repo(&info, repo_root) {
tracing::warn!(
"Shared dependency cache sync warning for {}: {error}",
info.path.display()View on GitHub (pinned to 01e15490f0)
Solutions
- Read the embedded {stderr} first — it names the exact git-level cause.
- If the branch already exists, reuse it or delete it (git branch -D) before retrying.
- Prune stale worktrees with `git worktree prune` and remove the target path if it is a leftover directory.
- Validate the branch name and path with git check-ref-format / path sanity before invoking git.
Example fix
// before
let info = create_worktree(repo_root, &path, &branch, base)?;
// after
// pre-flight: ensure no stale worktree/branch blocks creation
let _ = Command::new("git").arg("-C").arg(repo_root)
.args(["worktree", "prune"]).status();
let branch_taken = Command::new("git").arg("-C").arg(repo_root)
.args(["rev-parse", "--verify", "--quiet", &format!("refs/heads/{branch}")])
.status()?.success();
if branch_taken {
anyhow::bail!("branch {branch} already exists; reuse or delete it first");
}
let info = create_worktree(repo_root, &path, &branch, base)?; Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight checks that mirror git's own constraints.
use std::process::Command;
fn branch_exists(repo_root: &Path, branch: &str) -> bool {
Command::new("git").arg("-C").arg(repo_root)
.args(["rev-parse", "--verify", "--quiet", &format!("refs/heads/{branch}")])
.status().map(|s| s.success()).unwrap_or(false)
}
if branch_exists(repo_root, &branch) {
return Err(anyhow::anyhow!("branch {branch} already exists; reuse or delete it first"));
}
if path.exists() {
return Err(anyhow::anyhow!("worktree path {} already exists", path.display()));
} Type guard
fn worktree_creation_preconditions_ok(repo_root: &Path, path: &Path, branch: &str) -> bool {
!branch_exists(repo_root, branch) && !path.exists()
} Try / catch
match create_worktree(repo_root, &path, &branch, base) {
Ok(info) => { /* created */ }
Err(e) => {
let msg = e.to_string();
if msg.contains("git worktree add failed") {
// msg already embeds git's stderr; branch on it:
// - "already exists" -> prune / delete branch / pick a new path and retry
// - "not a valid object name HEAD" -> ensure HEAD has a commit (non-bare repo)
// - permission/disk -> fix environment
}
return Err(e);
}
} Prevention
- Run `git worktree prune` and clean leftover session paths before creating new worktrees.
- Validate branch names with `git check-ref-format --branch` before invoking git worktree add.
- Derive branch/path from a unique session id so collisions cannot happen across runs.
When it happens
Trigger: git worktree add fails: the branch already exists; the path is inside an existing worktree or is non-empty; HEAD is unborn (no commits) or detached in a bare repo; permission/disk errors; invalid characters in branch or path.
Common situations: Reusing a session_id whose branch already exists from a prior run; a previous crash left a worktree at that path; invalid branch-name characters; running against a fresh/bare clone with no HEAD commit.
Related errors
- worktree_branch_prefix cannot be empty
- git status failed: {stderr}
- git add failed for {path}: {stderr}
- git reset failed for {path}: {stderr}
- git restore failed for {}: {stderr}
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/8e51fecc84f70b74.
Report an issue: GitHub.