zed-industries/zed · error
git worktree add failed: {stderr}
Error message
git worktree add failed: {stderr} What it means
Creates a linked worktree with `git worktree add` (after creating the parent directory); a non-zero exit wraps git's stderr. Every git worktree-add failure mode appears here, and git's message names the precise problem.
Source
Thrown at crates/git/src/repository.rs:2230
&stdout,
main_worktree_path.as_deref(),
))
} else {
let stderr = String::from_utf8_lossy(&output.stderr);
anyhow::bail!("git worktree list failed: {stderr}");
}
})
.boxed()
}
fn worktree_created_at(
&self,
worktree_path: PathBuf,
) -> BoxFuture<'_, Result<Option<SystemTime>>> {
self.executor
.spawn(async move {
match std::fs::metadata(&worktree_path) {
Err(error) if error.kind() == std::io::ErrorKind::NotFound => {
return Ok(None);
}
Err(error) => {
return Err(error).with_context(|| {
format!("failed to stat {}", worktree_path.display())
});
}
Ok(_) => {}
}
let git_dir = linked_worktree_git_dir(&worktree_path)?;
let metadata = std::fs::metadata(&git_dir)
.with_context(|| format!("failed to stat {}", git_dir.display()))?;
let created_at = metadata.created().with_context(|| {
format!("creation time unavailable for {}", git_dir.display())
})?;
Ok(Some(created_at))
})
.boxed()View on GitHub (pinned to 5a9b9558db)
Solutions
- Read the appended stderr: for 'already checked out', pick another branch or reuse the existing worktree path.
- Clean the leftover target directory (or pass force) so `worktree add` finds no non-empty path.
- Verify the start point resolves: `git rev-parse --verify <start-point>`, and fetch if it only exists on the remote.
- Check write permission on the parent directory that was just created.
Defensive patterns
Strategy: validation
Validate before calling
// before add: target must be absent or empty, and the branch must not be checked out elsewhere
if path.exists() && std::fs::read_dir(&path)?.next().is_some() {
anyhow::bail!("worktree path {path:?} already exists and is not empty");
}
let checked_out = git
.run(&["worktree", "list", "--porcelain"])
.await?
.lines()
.filter(|l| l.starts_with("branch "))
.any(|l| l.ends_with(&format!("refs/heads/{branch}")));
anyhow::ensure!(!checked_out, "branch {branch} is already checked out in another worktree"); Try / catch
match repo.add_worktree(path, branch, None, false).await {
Err(e) if e.to_string().contains("already checked out") => {
// pick a different branch, or point the user at the existing worktree
}
Err(e) if e.to_string().contains("already exists") => {
// clean leftover directory or retry with force
}
other => other?,
} Prevention
- Check the target directory is empty before creating a worktree.
- Never check the same branch out in two worktrees; pick unique branches per worktree.
- Verify the start point resolves (`git rev-parse --verify`) before calling add.
When it happens
Trigger: `fatal: '<branch>' is already checked out at '<path>'` (same branch in two worktrees); `fatal: '<path>' already exists and is not an empty directory` (leftover from a previous attempt); invalid branch name; a start point (commit-ish) that does not resolve; permission denied creating the directory or the worktree.
Common situations: Opening the same branch in a second worktree; retrying worktree creation after a partial failure left files behind; passing a branch that exists only on an unfetched remote; CI sandboxes denying writes to the parent directory.
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
- git worktree list failed: {stderr}
- git status failed: {stderr}
- git diff-tree failed: {stderr}
- git merge-base failed: {stderr}
- git log command failed with {}: {}
AI-assisted analysis of zed-industries/zed@5a9b9558db (2026-08-20).
Data as JSON: /api/errors/b43ca9299277f01f.
Report an issue: GitHub.