Desktop sidebar: custom session groups permanently wiped on account switch (stripAccountSlice resets customGroups; migration edges still lossy)
Summary
Claude Desktop (Claude Code sidebar) permanently deletes all custom session groups when switching between two accounts in the same install. Both accounts' manually-built group structures are destroyed with no warning and no recovery path. Root cause confirmed by reverse-engineering the shipped bundles (details below). The new per-scope schema that recently deployed to claude.ai fixes the main wipe but has its own data-loss edges in the migration path.
Environment
- Claude Desktop (macOS, Intel), app shell v1.22209.0 — sidebar UI is served from claude.ai, so behavior is governed by web-bundle deploys, not the app version
- Two claude.ai accounts used alternately in the same desktop install
- Data lost ~2026-07-14; forensics done 2026-07-18
Root cause (old bundle, live until ~Jul 17/18 deploy)
The flat schema stored groups in Local Storage key dframe-store as top-level customGroups / customGroupAssignments / customGroupOrder. The settings-sync engine applies stripAccountSlice to every synced store on account switch (and again on reconcile when ccd-sync-owner ≠ current account). The old dframe registration strips groups to empty:
stripAccountSlice: e => ({
...
customGroups: [], // <- the wipe
customGroupAssignments: ...filter(([e]) => A_(e)), // keeps only cowork-space/artifact ids
customGroupOrder: ...filter(A_)...,
navPinnedIds: null, ...
})
With two accounts in one profile the flat list is shared, so the first switch deletes it, and the ex-owner is stripped again via owner-mismatch on the way back — both accounts end up empty. collapsedGroups is not stripped, which is why orphaned custom-cg-<uuid> references survive as the only trace. The server copy (PUT/GET /api/claude_code/organizations/<orgUuid>/user_settings, entry ccd/dframe-store, whose serverPartialize does include customGroups) did not restore the data on reconcile in our case.
Remaining data-loss edges in the NEW bundle (deployed ~Jul 17/18)
The new customGroupsByScope["<accountUuid>/<orgUuid>"] schema + pendingLegacyGroupMigration correctly preserves scopes across switches, but:
merge()unconditionally deletes the flat legacy keys; the stash intopendingLegacyGroupMigrationis skipped when they are empty — fine — but:onIdentityResolveclearspendingLegacyGroupMigrationwithout merging whensyncOwneris set and ≠ current account — silent drop of legacy groups.- On successful migration, legacy groups land in one scope only (the account active at migration time); the other account's view of the same shared legacy list is gone.
- The new
stripAccountSlicereplaces pending via a sanitizer that setsgroups: []— a switch mid-migration destroys the stashed names. - Users who hit the old wipe before the new schema deployed (our case) migrate nothing: the legacy fields were already
[], so the fix arrived too late and there is no attempt to fall back to the server copy ofccd/dframe-store.
Impact
Hours of manual sidebar organization (groups, assignments, ordering) destroyed for both accounts; users have no idea why, and nothing in the UI indicates group state is per-install, strip-on-switch, or unrecoverable. For heavy multi-session users the sidebar grouping IS the working memory of their project structure.
Asks
- Surface/restore path: on first load with empty
customGroupsByScope, offer to restore from the serverccd/dframe-storeentry if it contains a non-emptycustomGroups. - Fix edges 2–4 above (never clear
pendingLegacyGroupMigrationwithout merging; sanitize without emptying groups; migrate shared legacy groups into every known scope or prompt). - Never destructive-strip user-authored organization data without a backup breadcrumb (e.g., stash the stripped groups under a recovery key instead of
[]).
Repro (old bundle)
- Desktop install, account A: create custom groups in the Claude Code sidebar, assign sessions.
- Switch to account B (same install). Switch back to A.
- A's groups are gone (
customGroups: []), B never had them;collapsedGroupsstill references the deletedcustom-cg-*ids.
🤖 Filed with Claude Code on behalf of the affected user.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗