[BUG] Sidebar groups render based on stale 'order' key, not groups[] or member count — root cause + schema for #79810/#58193/#79156
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported with this level of detail (related: #79810, #58193, #79156, #65669 — all describe the symptom, none identify the actual data/rendering mechanism)
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
What's Wrong?
Custom sidebar groups (Desktop app, "Group by: Custom groups") intermittently fail to render even though their definitions are fully intact — confirmed by directly parsing the underlying LevelDB store rather than guessing from symptoms.
Where the data actually lives: ~/Library/Application Support/Claude/Local Storage/leveldb/, key _https://claude.ai\0dframe-store — a Zustand-persisted JSON blob (localStorage, not IndexedDB). Relevant shape:
{
"state": {
"customGroupsByScope": {
"<orgId>/<workspaceId>": {
"groups": [
{ "id": "cg-...", "name": "SomeGroup" }
],
"assignments": { "code:local_<sessionId>": "cg-..." },
"order": { "cg-...": ["code:local_<sessionId>", ...] }
}
},
"pendingLegacyGroupMigration": null
}
}
Root cause of the "some groups render, some don't" symptom (verified from live data, two real groups from the same account/scope, same moment in time):
Rendering is not based on current member count. It's based on whether the group has any key present in order at all:
- Group A had
"order": { "cg-XXXX": [] }— an empty array, but the key exists. Result: renders in the sidebar as an empty "Drag or move sessions here" dropzone. - Group B (and 8 others in the same scope) had no key at all in
orderfor their group id, despite existing ingroups[]and therefore still appearing in the "Move to group" context-menu list. Result: does not render in the sidebar at all, even though it's a fully valid, selectable group.
So a group that has never had a session explicitly filed into it via this UI (no order key ever created) is invisible in the sidebar, while a group that once had a session and lost it (empty array, but key retained) stays visible. groups[] (the definition list) and order/assignments (the render/membership state) are inconsistently read by different parts of the UI — the "Move to group" menu reads groups[] only, the sidebar list apparently requires an order entry.
Second finding — likely explains reports of groups losing all their old members ("permanently deleted", per #58193):
The oldest available local snapshot (earliest-dated file in the whole Local Storage store) already shows "assignments": {} and "order": {} for every group that existed at that point — not low, zero. The same JSON has a field named pendingLegacyGroupMigration, currently null. This strongly suggests there is (or was) a migration path meant to carry an older, pre-"custom groups" organization scheme (most likely the working-directory/git-root-derived auto-grouping described in #79156) into this new named-group + assignments/order schema — and for at least this account, it migrated the group names but not any historical membership, leaving assignments/order empty from day one for groups that the user remembers having had content.
What Should Happen?
- Sidebar rendering should be based on
groups[](show every defined group, consistently, regardless of current member count) — OR at minimum, "Move to group" and the sidebar list should agree on the same membership source. Right now they don't. - If
pendingLegacyGroupMigrationis a real migration flag, it should either actually carry old membership over, or the field/mechanism should be removed if it's dead code — right now it silently no-ops while implying migration happened. - Losing group membership should not be effectively unrecoverable client-side. At minimum, expose
order/assignmentsstate (or a "which sessions used to be here" hint) rather than only being reconstructable by parsing LevelDB directly.
Error Messages/Logs
No errors surfaced anywhere (UI, Console.app, or Claude Code debug logs) — this is a silent read/render inconsistency, not a crash.
Steps to Reproduce
- Have a Desktop app account with several custom groups, some of which have never had a session dragged into them since the "custom groups" feature was introduced (only defined via
groups[], noorderentry). - Switch
Group bytoCustom groups. - Observe: groups with an
orderentry (even[]) render; groups with none don't, despite both being valid, selectable entries in "Move to group". - To reproduce the "old members gone" symptom: pick a group that currently has zero entries in
assignments/order, use "Move to group" to file a session into it. Observe the group reappears in the sidebar with exactly the one just-added session — no trace of any session that may have been associated with that group name previously.
Claude Model
N/A — this is a Desktop app client-storage/rendering bug, unrelated to model choice.
Is this a regression?
Unknown — but pendingLegacyGroupMigration being null from the earliest available local snapshot suggests this may be present since the "custom groups" feature's introduction, not a recent regression.