anthropics / anthropics/claude-code
[BUG] Sidebar groups render based on stale 'order' key, not groups[] or member count — root cause + schema for #79810/#58193/#79156
- 主要语言
- Python
- 星标
- 145k
- 派生
- 23.1k
- PR 合并指标
- PR 指标待抓取
描述
### 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:
```json
{
"state": {
"customGroupsByScope": {
"/": {
"groups": [
{ "id": "cg-...", "name": "SomeGroup" }
],
"assignments": { "code:local_": "cg-..." },
"order": { "cg-...": ["code:local_", ...] }
}
},
"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.
贡献指南
这个仓库没有索引到贡献指南
调研方向
Reproduce with Desktop app custom groups and inspect the persisted blob at ~/Library/Application Support/Claude/Local Storage/leveldb/ key _https://claude.ai\0dframe-store. Trace the UI paths that read groups[], order, assignments, and pendingLegacyGroupMigration. Done means the sidebar and Move to group menu use consistent group state, with migration behavior clarified or fixed.
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- javascript, json, macos
- 领域
- data, desktop, frontend
- Issue 类型
- 缺陷
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 活跃
- 描述清晰度
- 基本清楚
- 新手友好度
- 48/100