[BUG] Sidebar groups render based on stale 'order' key, not groups[] or member count — root cause + schema for #79810/#58193/#79156

Status Open
Maintainer reply None cached
Activity 0 comments · opened Sep 9, 2026

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 order for their group id, despite existing in groups[] 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?

  1. 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.
  2. If pendingLegacyGroupMigration is 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.
  3. Losing group membership should not be effectively unrecoverable client-side. At minimum, expose order/assignments state (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

  1. 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[], no order entry).
  2. Switch Group by to Custom groups.
  3. Observe: groups with an order entry (even []) render; groups with none don't, despite both being valid, selectable entries in "Move to group".
  4. 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.

View original on GitHub ↗