affaan-m/ECC · error

git worktree add failed

Error message

git worktree add failed: {stderr}

What it means

create_for_session_in_repo shells out to `git worktree add <path> -b <branch> HEAD`. If the git process exits non-zero, the raw stderr is surfaced as this error so the caller knows why the worktree could not be created.

Solutions

  1. Remove the stale worktree (`git worktree remove <path>`) and delete the stale branch (`git branch -D <branch>`) before retrying
  2. Read the stderr in the error message — 'already exists', 'invalid reference', or 'not a git repository' each point to a different cause
  3. Commit at least one commit in the repo (worktree add HEAD requires a valid HEAD)
  4. Ensure the parent directory for the worktree path is writable

Example fix

// before
create_for_session(&session_id, &cfg).await?;
// after
let path = worktree_path_for(&session_id);
if Path::new(&path).exists() {
    Command::new("git").args(["worktree", "remove", path_str]).output()?;
}
create_for_session(&session_id, &cfg).await?;
Defensive patterns

Strategy: try-catch

Validate before calling

// Check prerequisites before calling create_for_session
if !repo_root.join(".git").exists() { bail!("not a git repository"); }
let branch = format!("{prefix}/{session_id}");
let exists = Command::new("git").args(["rev-parse", "--verify", &branch]).output()?.status.success();
if exists { bail!("branch {branch} already exists"); }

Try / catch

match create_for_session(&session_id, &cfg).await {
    Ok(wt) => wt,
    Err(e) if e.to_string().contains("already exists") => {
        cleanup_stale_worktree(&session_id)?;
        create_for_session(&session_id, &cfg).await?
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling create_for_session when the target worktree path already exists, the derived branch name already exists, HEAD is unborn (empty repo), or git cannot write to the parent directory.

Common situations: A stale worktree directory left behind by a crashed session; a previous run already created the branch with the same prefix/session-id; running inside a repo with no commits yet; read-only or full filesystem.

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/8e51fecc84f70b74. Report an issue: GitHub.

Appendix: 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 8321021c54)