fix(#4662): clear workspace skeleton on switch-failure no-workspace path

The success path clears a stranded workspace-tree skeleton when the new
profile has no bound workspace (both switch branches), but the catch block
only restored the tree `if (S.session && S.session.workspace)` — with no
else. So a profile-switch failure while the workspace panel is open and the
(still-current) previous session has no workspace left the up-front skeleton
shimmering forever: the same skeleton-strand class the Codex/Opus gates
targeted, in the one path they didn't cover. Mirror the success-path
no-workspace handling in the failure path. Adds a static regression
assertion that the catch block clears the workspace skeleton.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nathan EsquenaziandClaude Opus 4.8 authored and nesquena-hermes committed 2026-06-22 18:12:55 +00:00
1 parent e505543650
commit ef0b4ba37a
2 files changed
+16

No files matched your search

+5
View File
@@ -6113,6 +6113,11 @@ async function switchToProfile(name) {
}
if (_workspaceVisibleAtStart && S.session && S.session.workspace && typeof loadDir === 'function') {
loadDir('.');
} else if (_workspaceVisibleAtStart && typeof clearWorkspaceTreeSkeleton === 'function') {
// No workspace to restore on the (still-current) previous profile —
// clear the up-front workspace skeleton so it doesn't strand on a switch
// failure, mirroring the success-path no-workspace handling (#4662).
clearWorkspaceTreeSkeleton();
}
}
} finally {
@@ -58,6 +58,17 @@ class TestSwitchWiring:
catch = body[body.index("} catch (e) {"):]
assert "renderSessionListFromCache()" in catch, "failed switch must restore real list"
def test_failure_path_clears_workspace_skeleton_when_no_workspace(self):
# The success path clears a stranded workspace skeleton when the profile
# has no bound workspace; the failure path must do the same — otherwise a
# switch failure while the workspace panel is open and the (still-current)
# session has no workspace strands the up-front skeleton forever (#4662).
body = _switch_body()
catch = body[body.index("} catch (e) {"):]
assert "clearWorkspaceTreeSkeleton()" in catch, (
"failed switch must clear the workspace skeleton when there's no workspace to restore"
)
def test_noop_self_switch_early_returns(self):
# Opus gate #4662: a switch to the already-active profile must bail before
# showing a skeleton (activateCurrentProfile() doesn't pre-check), else it