From 4b488190728c7ff08b22bc4b331070dc0459b1ea Mon Sep 17 00:00:00 2001 From: Anthony Eid <56899983+Anthony-Eid@users.noreply.github.com> Date: Mon, 20 Apr 2026 17:18:09 -0400 Subject: [PATCH] agent: When opening a remote thread check that the linked worktree path exists (#54353) If the path doesn't exist we fallback to the main worktree path. This handles the edge case where a git linked worktree is deleted on a remote machine, and a user tries to open a thread based on that. We fallback to the main git worktree in this case, if that doesn't exist the project will open in an error state (empty workspace) like we already do Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Closes #ISSUE Release Notes: - N/A --- crates/workspace/src/multi_workspace.rs | 29 ++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/crates/workspace/src/multi_workspace.rs b/crates/workspace/src/multi_workspace.rs index 23ee3c0ab876f54bd03b6fb0399daddd5650254c..0752dd2e3f3e6d9a01656ad72b6ba5adc67edcc6 100644 --- a/crates/workspace/src/multi_workspace.rs +++ b/crates/workspace/src/multi_workspace.rs @@ -1213,13 +1213,40 @@ impl MultiWorkspace { ) }); + let effective_paths_vec = + if let Some(project_group) = provisional_project_group_key.as_ref() { + let resolve_tasks = cx.update(|cx| { + let project = new_project.read(cx); + paths_vec + .iter() + .map(|path| project.resolve_abs_path(&path.to_string_lossy(), cx)) + .collect::>() + }); + let resolved = futures::future::join_all(resolve_tasks).await; + // `resolve_abs_path` returns `None` for both "definitely + // absent" and transport errors (it swallows the error via + // `log_err`). This is a weaker guarantee than the local + // `Ok(None)` check, but it matches how the rest of the + // codebase consumes this API. + let all_paths_missing = + !paths_vec.is_empty() && resolved.iter().all(|resolved| resolved.is_none()); + + if all_paths_missing { + project_group.path_list().paths().to_vec() + } else { + paths_vec + } + } else { + paths_vec + }; + let window_handle = window_handle.ok_or_else(|| anyhow::anyhow!("Window is not a MultiWorkspace"))?; open_remote_project_with_existing_connection( connection_options, new_project, - paths_vec, + effective_paths_vec, app_state, window_handle, provisional_project_group_key,