zed-industries/zed · warning
worktree not found
Error message
worktree not found
What it means
The directory-mention flow resolved a ProjectPath (which embeds worktree_id) and immediately calls project.worktree_for_id; None means the worktree was removed from the project in between. Because the id came from a worktree that existed a moment earlier, this is a teardown/removal race rather than a bad path.
Source
Thrown at crates/agent_ui/src/mention_set.rs:1260
files
}
let Some(project_path) = project
.read(cx)
.project_path_for_absolute_path(&abs_path, cx)
else {
return Task::ready(Err(anyhow!(
"project path not found for directory mention {abs_path:?}"
)));
};
let Some(entry) = project.read(cx).entry_for_path(&project_path, cx) else {
return Task::ready(Err(anyhow!("project entry not found")));
};
let directory_path = entry.path.clone();
let worktree_id = project_path.worktree_id;
let Some(worktree) = project.read(cx).worktree_for_id(worktree_id, cx) else {
return Task::ready(Err(anyhow!("worktree not found")));
};
let project = project.clone();
cx.spawn(async move |cx| {
let file_paths = worktree.read_with(cx, |worktree, _cx| {
collect_files_in_path(worktree, &directory_path)
});
let descendants_future = cx.update(|cx| {
futures::future::join_all(file_paths.into_iter().map(
|(worktree_path, full_path): (Arc<RelPath>, String)| {
let rel_path = worktree_path
.strip_prefix(&directory_path)
.map_or_else(|_| worktree_path.clone(), |rel_path| rel_path.into());
let open_task = project.update(cx, |project, cx| {
project.buffer_store().update(cx, |buffer_store, cx| {
let project_path = ProjectPath {
worktree_id,
path: worktree_path,View on GitHub (pinned to bc538def45)
Solutions
- Retry the mention after the project settles; the path re-resolves against the remaining worktrees.
- Treat as cancellation if the window is closing.
- In code, re-validate that the worktree still exists right before use and surface a 'directory no longer available' message.
Defensive patterns
Strategy: validation
Validate before calling
// re-resolve the worktree immediately before spawning the async work
let Some(worktree) = project.read(cx).worktree_for_id(project_path.worktree_id, cx) else {
return Task::ready(Err(anyhow!("directory no longer available")));
}; Try / catch
match confirm_task.await {
Ok(mention) => { /* attach */ }
Err(err) if err.to_string() == "worktree not found" => {
show_user("That worktree was removed from the project")
}
Err(err) => return Err(err),
} Prevention
- Capture a strong Entity<Worktree> handle once resolved, and check it is alive before use.
- Recompute project paths when worktrees are removed instead of caching ids.
- Treat this as a transient race: offer the user a retry after the project settles.
When it happens
Trigger: Removing or closing a worktree from the project while a directory mention confirmation is running; project teardown racing the spawned mention task.
Common situations: Closing a multi-root project's root just as a mention is confirmed; rapid workspace restructuring; tests exercising removal races.
Related errors
- project path not found for symbol mention {abs_path:?}
- project path not found for directory mention {abs_path:?}
- project entry not found
- Could not find UNIT_DATA in the file
- HTTP error! status: ${response.status}
AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16).
Data as JSON: /api/errors/04f24dc6f61d5f5b.
Report an issue: GitHub.