zed-industries/zed · error

A worktree already exists at {}

Error message

A worktree already exists at {}

What it means

When Zed creates linked worktrees, it computes each repository's target directory via path_for_new_linked_worktree(worktree_name, dir). If that path is already present in existing_worktree_paths, the service bails rather than letting 'git worktree add' clobber or duplicate a checkout. It is a name/path collision detected up front.

Source

Thrown at crates/git_ui_core/src/worktree_service.rs:495

    )>,
    Vec<(PathBuf, PathBuf)>,
)> {
    let mut creation_infos = Vec::new();
    let mut path_remapping = Vec::new();
    let mut scheduled_paths: HashSet<PathBuf> = HashSet::default();

    let worktree_name = worktree_name.unwrap_or_else(|| {
        let existing_refs: Vec<&str> = existing_worktree_names.iter().map(|s| s.as_str()).collect();
        worktree_names::generate_worktree_name(&existing_refs, rng)
            .unwrap_or_else(|| "worktree".to_string())
    });

    for repo in git_repos {
        let (work_dir, new_path, receiver) = repo.update(cx, |repo, _cx| {
            let new_path =
                repo.path_for_new_linked_worktree(&worktree_name, worktree_directory_setting)?;
            if existing_worktree_paths.contains(&new_path) {
                anyhow::bail!("A worktree already exists at {}", new_path.display());
            }
            let work_dir = repo.work_directory_abs_path.clone();
            // Only the first repo that resolves to a given target path
            // actually creates the worktree; subsequent linked worktrees of
            // the same repository just contribute a path remapping.
            let receiver = if scheduled_paths.contains(&new_path) {
                None
            } else {
                let target = git::repository::CreateWorktreeTarget::Detached {
                    base_sha: base_ref.clone(),
                };
                Some(repo.create_worktree(target, new_path.clone()))
            };
            anyhow::Ok((work_dir, new_path, receiver))
        })?;
        path_remapping.push((work_dir.to_path_buf(), new_path.clone()));
        if let Some(receiver) = receiver {
            scheduled_paths.insert(new_path.clone());

View on GitHub (pinned to f4178619ac)

Solutions

  1. Omit the explicit name so generate_worktree_name picks a unique one against existing refs, or choose a different name
  2. If the old worktree is stale, remove it first (git worktree remove <path>, then git worktree prune)
  3. If the name must be reused, move or retire the existing directory before creating again
  4. Check worktree_directory_setting: a shared fixed directory makes collisions far more likely

Example fix

// before
start_worktree_creations(&repos, Some("feature-x".into()), ..) // 'feature-x' already on disk -> bail

// after: let the generator avoid existing names
start_worktree_creations(&repos, None, ..)
Defensive patterns

Strategy: validation

Validate before calling

// before asking the service to create worktrees
let target = repo.read(cx).path_for_new_linked_worktree(&name, dir)?;
if existing_worktree_paths.contains(&target) {
    // pick a different name or prune the stale worktree instead of erroring
}

Try / catch

match start_worktree_creations(&repos, Some(name.clone()), ..) {
    Ok(result) => { /* ... */ }
    Err(err) if err.to_string().contains("worktree already exists") => {
        // regenerate a unique name and retry once, or offer to open the existing worktree
    }
    Err(err) => return Err(err),
}

Prevention

When it happens

Trigger: Calling multi-repo worktree creation with an explicit worktree_name that already exists on disk for one of the repos; two repositories in the project resolving to the same target directory for the chosen name; re-running the create-worktree flow with the same custom name after a previous run.

Common situations: User re-invokes worktree creation with a previously used name; stale worktree directories left behind after aborted runs; a fixed worktree_directory_setting that funnels every worktree to one location.

Related errors


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/82aaac05d3c7afc9. Report an issue: GitHub.