Skip to content

Fix ghost project when selecting remote project group - #59272

Merged
Veykril merged 3 commits into
zed-industries:mainfrom
procr1337:fix-ghost-projects
Jun 15, 2026
Merged

Fix ghost project when selecting remote project group#59272
Veykril merged 3 commits into
zed-industries:mainfrom
procr1337:fix-ghost-projects

Conversation

@procr1337

@procr1337 procr1337 commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Objective

Fixes #54882:

When selecting a project group that has a remote host (SSH, WSL, Docker) from the window project picker, or when closing/removing a workspace with a remote neighbor group, the code was unconditionally calling find_or_create_local_workspace. This created a local project with the remote server's paths, producing a 'ghost' project where language servers and file watchers fail trying to access paths that don't exist locally.

Solution

Three locations fixed:

  1. RecentProjectsDelegate::confirm (recent_projects.rs) - window project picker selecting a ProjectGroup entry. Routes to find_or_create_workspace with connect_with_modal for remote hosts.

  2. MultiWorkspace::close_workspace (multi_workspace.rs) - closing a workspace whose neighboring group is remote. Falls through to the empty workspace fallback instead of creating a ghost project.

  3. MultiWorkspace::remove_project_group (multi_workspace.rs) - removing a project group whose neighbor is remote. Same fallback.

All three detect remoteness via key.host().is_some() and skip find_or_create_local_workspace when set.

Includes regression tests for all three paths using mock remote connections.

Testing

  • Not yet tested with a custom build
  • Unit tests added

Self-Review Checklist:

  • I've reviewed my own diff for quality, security, and reliability
  • Unsafe blocks (if any) have justifying comments
  • The content adheres to Zed's UI standards (UX/UI and icon guidelines)
  • Tests cover the new/changed behavior
  • Performance impact has been considered and is acceptable

Showcase


Release Notes:

  • Fixed ghost project appearing in the window project picker and sidebar when switching between local and remote projects.

When selecting a project group that has a remote host (SSH, WSL, Docker)
from the window project picker, or when closing/removing a workspace
with a remote neighbor group, the code was unconditionally calling
find_or_create_local_workspace. This created a local project with the
remote server's paths, producing a 'ghost' project where language
servers and file watchers fail trying to access paths that don't exist
locally.

Three locations fixed:

1. RecentProjectsDelegate::confirm (recent_projects.rs) - window
   project picker selecting a ProjectGroup entry. Routes to
   find_or_create_workspace with connect_with_modal for remote hosts.

2. MultiWorkspace::close_workspace (multi_workspace.rs) - closing a
   workspace whose neighboring group is remote. Falls through to the
   empty workspace fallback instead of creating a ghost project.

3. MultiWorkspace::remove_project_group (multi_workspace.rs) - removing
   a project group whose neighbor is remote. Same fallback.

All three detect remoteness via key.host().is_some() and skip
find_or_create_local_workspace when set.

Includes regression tests for all three paths using mock remote
connections.
@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label Jun 13, 2026
@ChristopherBiscardi ChristopherBiscardi added the area:workspace Feedback for workspace management, layout, interactions, etc label Jun 15, 2026
@Veykril Veykril self-assigned this Jun 15, 2026
@Veykril
Veykril self-requested a review June 15, 2026 06:53
Comment on lines +1198 to +1228
if host.is_some() {
let modal_workspace = multi_workspace.workspace().clone();
multi_workspace.find_or_create_workspace(
path_list,
host,
Some(key.clone()),
move |options, window, cx| {
connect_with_modal(
&modal_workspace,
options,
window,
cx,
)
},
&[],
None,
OpenMode::Activate,
window,
cx,
)
} else {
multi_workspace.find_or_create_local_workspace(
path_list,
Some(key.clone()),
&[],
None,
OpenMode::Activate,
window,
cx,
)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can just be

Suggested change
if host.is_some() {
let modal_workspace = multi_workspace.workspace().clone();
multi_workspace.find_or_create_workspace(
path_list,
host,
Some(key.clone()),
move |options, window, cx| {
connect_with_modal(
&modal_workspace,
options,
window,
cx,
)
},
&[],
None,
OpenMode::Activate,
window,
cx,
)
} else {
multi_workspace.find_or_create_local_workspace(
path_list,
Some(key.clone()),
&[],
None,
OpenMode::Activate,
window,
cx,
)
}
let modal_workspace = multi_workspace.workspace().clone();
multi_workspace.find_or_create_workspace(
path_list,
host,
Some(key.clone()),
move |options, window, cx| {
connect_with_modal(
&modal_workspace,
options,
window,
cx,
)
},
&[],
None,
OpenMode::Activate,
window,
cx,
)

@procr1337
procr1337 requested a review from Veykril June 15, 2026 08:40

@Veykril Veykril left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@Veykril
Veykril enabled auto-merge June 15, 2026 08:48
Comment thread crates/recent_projects/src/recent_projects.rs Outdated
@Veykril
Veykril added this pull request to the merge queue Jun 15, 2026
Merged via the queue into zed-industries:main with commit 338530f Jun 15, 2026
32 checks passed
This was referenced Jun 18, 2026
jolutz pushed a commit to jolutz/zed that referenced this pull request Aug 8, 2026
…#59272)

# Objective

Fixes zed-industries#54882:

When selecting a project group that has a remote host (SSH, WSL, Docker)
from the window project picker, or when closing/removing a workspace
with a remote neighbor group, the code was unconditionally calling
find_or_create_local_workspace. This created a local project with the
remote server's paths, producing a 'ghost' project where language
servers and file watchers fail trying to access paths that don't exist
locally.

## Solution

Three locations fixed:

1. RecentProjectsDelegate::confirm (recent_projects.rs) - window project
picker selecting a ProjectGroup entry. Routes to
find_or_create_workspace with connect_with_modal for remote hosts.

2. MultiWorkspace::close_workspace (multi_workspace.rs) - closing a
workspace whose neighboring group is remote. Falls through to the empty
workspace fallback instead of creating a ghost project.

3. MultiWorkspace::remove_project_group (multi_workspace.rs) - removing
a project group whose neighbor is remote. Same fallback.

All three detect remoteness via key.host().is_some() and skip
find_or_create_local_workspace when set.

Includes regression tests for all three paths using mock remote
connections.

## Testing

- Not yet tested with a custom build
- Unit tests added

## 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 adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

---

Release Notes:

- Fixed ghost project appearing in the window project picker and sidebar
when switching between local and remote projects.

---------

Co-authored-by: Lukas Wirth <me@lukaswirth.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:workspace Feedback for workspace management, layout, interactions, etc cla-signed The user has signed the Contributor License Agreement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mix of remote and local projects breaks the multi agent sidebar project selector

3 participants