diff --git a/apps/desktop/src/app/chat/sidebar/profile-switcher.tsx b/apps/desktop/src/app/chat/sidebar/profile-switcher.tsx index c92883ed3..783bc17a2 100644 --- a/apps/desktop/src/app/chat/sidebar/profile-switcher.tsx +++ b/apps/desktop/src/app/chat/sidebar/profile-switcher.tsx @@ -264,16 +264,7 @@ export function ProfileRail() { setPendingDelete(null)} - onDeleted={async () => { - // Deleting the profile you're currently in would strand the gateway on - // a dead profile — fall back to default. - const wasActive = pendingDelete != null && normalizeProfileKey(pendingDelete.name) === activeKey - await refreshActiveProfile() - - if (wasActive) { - selectProfile('default') - } - }} + onDeleted={refreshActiveProfile} open={pendingDelete !== null} profile={pendingDelete} /> diff --git a/apps/desktop/src/app/profiles/delete-profile-dialog.tsx b/apps/desktop/src/app/profiles/delete-profile-dialog.tsx index a1a0a49d9..a0406203d 100644 --- a/apps/desktop/src/app/profiles/delete-profile-dialog.tsx +++ b/apps/desktop/src/app/profiles/delete-profile-dialog.tsx @@ -1,8 +1,10 @@ import { ConfirmDialog } from '@/components/ui/confirm-dialog' import { deleteProfile } from '@/hermes' +import { $activeGatewayProfile, normalizeProfileKey, selectProfile, setActiveProfile } from '@/store/profile' // Thin wrapper over ConfirmDialog: owns the deleteProfile call, inherits -// Enter-to-confirm + busy/done/error from the shared dialog. +// Enter-to-confirm + busy/done/error from the shared dialog. The single choke +// point for every delete entry point (rail + Profiles view). export function DeleteProfileDialog({ profile, onClose, @@ -34,8 +36,20 @@ export function DeleteProfileDialog({ return } + // Deleting the profile the live gateway is on strands it on a dead + // backend. Capture that before the delete; reset *after* the host's + // onDeleted refresh so our reset is the last write — a refreshActiveProfile + // racing the (still-dying) backend can't clobber the pill back to it. + const wasActive = normalizeProfileKey(profile.name) === normalizeProfileKey($activeGatewayProfile.get()) await deleteProfile(profile.name) await onDeleted?.() + + if (wasActive) { + // Swap gateway/sidebar to default and set the pill now — the primary + // backend is always default, so this is correct, not just optimistic. + selectProfile('default') + setActiveProfile('default') + } }} open={open} title="Delete profile?"