Repository navigation
[Bug]: Removing a paired remote server leaves an orphaned empty project group that cannot be deleted #18364
Description
Summary
Removing a paired remote server (runtime environment) in Settings leaves an
orphaned empty project group in the sidebar. The leftover group can never be
deleted: deleting it always shows the toast "Failed to delete group /
Something went wrong while deleting the group. No projects were removed."
Only a full Orca restart clears the row.
Environment
- Orca 1.4.195, macOS
- One local profile (no SSH targets); the group came from a paired remote server.
Repro
- Settings → Runtime environments → add and connect a paired remote server.
Its runtime-owned project group appears in the sidebar (the group was
auto-created when the server was linked; the server's agents/workspaces
live under it). - Settings → Runtime environments → Remove that server. The server's agents
and workspaces are removed, but an empty project-group row stays in the
sidebar. - Click delete on the leftover group and confirm → toast "Failed to delete
group / Something went wrong while deleting the group. No projects were
removed." - The row only disappears after quitting and relaunching Orca.
Expected
Removing a paired remote server should also remove its mirrored project-group
row. At minimum, deleting a group whose owning runtime no longer exists should
succeed and just clear the row — the sidebar must never keep an undeletable
orphan.
Actual
The empty group row remains until restart, and delete fails while it is there.
Root cause analysis
- Project groups mirrored from a runtime environment are renderer-only rows
stamped withexecutionHostId: "runtime:<envId>"; they are never persisted
(executionHostIdis deliberately not written toorca-data.json— the
local profile stays atprojectGroups: []even while such a group is shown).
This is why a restart clears the row. - When a server is removed,
runtime-status.tscomputesretiredEnvironmentIds
and callspurgeStaleRuntimeHostState(retiredEnvironmentIds). createPurgeStaleRuntimeHostState
(src/renderer/src/store/slices/worktrees/teardown/purge-stale-runtime-host-state.ts)
purges that host'srepos,projectHostSetups,worktreesByRepo, detected
worktrees, restored-session owners, and visibility defaults — but never
touchess.projectGroups. The runtime-owned group row is the one leftover.- Deleting the leftover group routes to its owner host
(resolveProjectGroupOwnerHostIdinproject-group-owner-routing.ts), which
is now a deadruntime:<envId>; the call returns false and the UI surfaces
groupDeleteFailed. There is no "owner already gone" fallback.
Proposed fix 1 (root cause): purge runtime-owned groups on env removal
In purge-stale-runtime-host-state.ts, inside the set() updater, also drop
project groups owned by removed runtime environments, mirroring the existing
applyProjectGroupDeleteCascade
(src/renderer/src/store/project-groups/project-group-removal-state.ts):
- collect group ids whose owner host is a removed
runtime:<envId>
(reusegetProjectGroupHostIdfor the same owner-resolution used by delete),
expanded to their subtree viagetProjectGroupSubtreeIds; - filter those out of
s.projectGroups(onlyruntime:owners — local/SSH
groups must be untouched); - cascade: drop
folderWorkspacesreferencing the dropped groups, unset
projectGroupIdon any surviving repo, and add agroupsChangedflag to the
existing early-return guard and the returned state (bumpsortEpochwhen it
changes).
Proposed fix 2 (defense in depth): deleting an orphan group succeeds
In deleteProjectGroupWithContainedProjects
(src/renderer/src/store/project-groups/project-group-mutations.ts), when the
delete returns false and the group's owner host is a runtime:* environment
that no longer exists in the environment catalog, treat it as already-deleted:
cascade the row out of s.projectGroups and return deleted-group (the code
already treats missing-group as a silent success). This guarantees no orphan
row is ever a permanent UI dead end, including leftovers created before fix 1.
Related
- Project group delete/rename always fails when a remote host is the active runtime #14849 — delete/rename fails while a remote host is the active runtime
(same toast; different trigger — the group's owner still exists there) - [Bug]: Project group creation always routes to the active runtime, so groups get created on the wrong host #15006 — group creation routes to the active runtime instead of the owner
- [Bug]: Can't rename or delete a folder-scan project group (UI dead end) #14007 — folder-scan group became an undeletable UI dead end
- fix: correct agent commands, shell hooks, and runtime routing #14838 (open PR) — owner-routed mutations; does not cover a removed owner
Happy to open a PR for fix 1 (+ fix 2) if maintainers prefer a code proposal.
Activity
CreateSun commentedon Sep 3, 2026
Opened PR #18369 implementing fix 1 (purge runtime-owned project groups when the paired server is removed). Renderer-store only, with regression tests in
purge-stale-runtime-host-project-groups.test.ts; the delete-orphan fallback (fix 2) remains a possible follow-up.OrcaWin commentedon Oct 9, 2026
This should be fixed on main by #24863: removing a paired server now also clears the project groups it owned, so the empty undeletable row no longer sticks around. If you still see it on a current build, please reopen with the steps and we'll take another look.