anthropics / anthropics/claude-code

Restarting Claude Desktop on two machines registers each device twice; sessions then leave their project group and appear under "Other" on the other machine

Đang mở
#92,318 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
area:desktop bug platform:windows
Ngôn ngữ chính
Python
Star
145k
Fork
23.1k
Chỉ số merge pull request
Chỉ số pull request đang chờ

Mô tả

### Preflight Checklist

- [x] I have searched [existing issues](https://github.com/anthropics/claude-code/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug) and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code

### What's Wrong?

I restarted Claude Desktop on two Windows machines about 1–2 minutes apart, both signed in to the same account. Within the next few minutes:

1. The account emitted **four** "A new trusted device was added to your Claude account" alerts — **two per machine** — even though only two devices were involved, and neither machine's locally stored device identity changed.
2. Claude Code sessions belonging to a project on Machine B **disappeared from that project's group** in Machine B's sidebar, and showed up under **"Other"** in Machine A's sidebar instead.

No conversation data was lost — every transcript is still on disk on the machine that created it, and (for the affected project) with a valid index entry. The failure is in the session list / project grouping layer. But the user-visible effect is indistinguishable from data loss, which is how I first read it; it took a fairly deep filesystem investigation to establish that the transcripts were fine.

**The leakage is bidirectional.** Machine A's sidebar lists 8 sessions from Machine B under "Other"; Machine B's sidebar lists 4 sessions from Machine A under "Other". Foreign sessions carry no indication of which machine they came from — their `cwd` values point at drive letters that do not exist on the machine displaying them.

**The state persists.** Hours and several restarts later, the four large sessions written that day (2.78 MB, 19.16 MB, 2.43 MB, 4.10 MB) are still absent from their project group on Machine B, while their transcripts sit on disk with valid index entries. The group now lists only two sessions started *after* the incident and four from two to three days *before* it.

Full evidence, timeline and the index/transcript reconciliation for both machines are in **Additional Information** below.

### What Should Happen?

- Restarting the desktop app should not register a device that is already trusted, and should certainly not register the same device twice in a single restart.
- Sessions created on a machine should stay listed under their project group on that machine.
- Sessions belonging to a different machine, if they are shown at all, should indicate where they came from rather than landing in an unlabelled "Other" bucket.

### Error Messages/Logs

```shell

```

### Steps to Reproduce

**Caveat up front: I have not tried to reproduce this deliberately.** These are the steps that produced it once. The near-simultaneous restart of two machines is the only unusual element I can identify.

1. Sign the same account into Claude Desktop on two Windows machines. Use different Windows usernames on each, and keep projects on different drive letters, so that the two `%USERPROFILE%\.claude\projects` trees share no path prefix and no encoded project directory name exists on both.
2. Do Claude Code work in a project on each machine, so each has sessions with transcripts on disk.
3. Restart Claude Desktop on both machines within 1–2 minutes of each other.
4. Check the account's security alerts. In my case four "A new trusted device was added to your Claude account" emails arrived within two minutes — two per machine, each pair sharing one device string and one IP.
5. A few minutes later, check both sidebars.

Observed at step 5:

- On the machine whose project was affected, that project's group no longer lists the sessions worked on that day, although the project folder itself is still in the sidebar.
- On the other machine, those sessions appear under "Other", with no indication of their origin.
- The transcripts are all still on disk, and (on the affected machine) all still have valid `local_*.json` index entries.

This did not resolve on subsequent restarts.

### Claude Model

None

### Is this a regression?

Yes, this worked in a previous version

### Last Working Version

_No response_

### Claude Code Version

2.1.260 (Desktop-bundled); Claude Desktop 1.46338.4.0

### Platform

Anthropic API

### Operating System

Windows

### Terminal/Shell

PowerShell

### Additional Information

## Environment

| | Machine A | Machine B |
|---|---|---|
| OS | Windows 11 Pro (build 26200) | Windows 11 Pro |
| Claude Desktop | 1.46338.4.0 | 1.46338.4.0 |
| Install type | standard, app data under `%APPDATA%\Claude\` | **MSIX / Store**, app data under `%LOCALAPPDATA%\Packages\Claude_\LocalCache\Roaming\Claude\` |
| Claude Code | Desktop-bundled builds 2.1.258 and 2.1.260 present | Desktop-bundled only, no standalone CLI installed |
| Project root | `F:\Project\` | `E:\Projects\\` |
| Transcript dir | `C:\Users\\.claude\projects\` | `C:\Users\\.claude\projects\` |
| Network | network 1 | network 2 (different public IP) |

Both machines were being viewed over RDP from a Mac at the time; the Claude Desktop processes themselves run natively on the Windows machines. Same account on both. Windows usernames differ, so the two `.claude\projects` trees share no path prefix.

Claude Code encodes the project path into the transcript directory name, e.g. `E:\Projects\\` becomes `E--Projects--`. Because the two machines use different drive letters and different usernames, no project directory name exists on both.

## Timeline

Local times are UTC+08:00. Alert times are in UTC as they appear in the emails.

| Local time | Where | Event |
|---|---|---|
| ~19:08–19:10 | both | Claude Desktop restarted on both machines, 1–2 minutes apart (to pick up an edited global config file) |
| 19:10 | Machine A | App start — `~/.claude/session-env/`, `~/.claude/sessions/.json` and a `.claude.json` backup all written |
| 11:14 UTC | account | **2 ×** "A new trusted device was added to your Claude account" — Device: `Electron on Windows · `, IP #1 |
| 11:15 UTC | account | **2 ×** same alert — Device: `Electron on Windows · `, IP #2 |
| 19:18:23–19:18:29 | Machine B | The **four largest transcripts of one project** rewritten inside a 6-second window: 2.78 MB, 19.16 MB, 2.43 MB, 4.10 MB |
| 19:19:18 | Machine B | Another transcript in that project written (104 KB) |
| 19:19:20 | Machine B | `buddy-tokens.json` rewritten |
| 19:30:15 | Machine B | Another transcript in that project written (98 KB) |
| 19:31:53 | Machine A | `buddy-tokens.json` rewritten |

The six-second rewrite window at 19:18 hits exactly the project whose sessions then went missing from its group, roughly three minutes after the device-registration alerts.

## Evidence

### A. Transcripts are intact on disk — this is not data loss

On Machine B every transcript for the affected project is present, including all of the day's sessions (6 files written that day, 98 KB to 19.2 MB). They remain resumable with `claude --resume ` from that directory.

### B. The sidebar and the session-management API disagree on the same machine

On Machine A the sidebar lists 8 foreign sessions under "Other". The desktop app's own session-management API on that machine returns only **6** sessions, all with local `cwd` values, and none of the 8. Two views inside the same app disagree about what sessions exist.

### C. Device registration anomaly

```
11:14 UTC Electron on Windows · IP #1 ×2
11:15 UTC Electron on Windows · IP #2 ×2
```

Each physical machine produced two trusted-device registrations from one restart.

### D. Local device identity files were not touched

| File | Machine A mtime | Machine B mtime |
|---|---|---|
| `ant-did` | 2026-09-01 12:37 | 2026-04-10 13:40 |
| `ant-device-registry.json` | 2026-09-01 12:39 | 2026-08-24 20:55 |
| `buddy-tokens.json` | 2026-09-05 **19:31:53** | 2026-09-05 **19:19:20** |

The server registered new trusted devices while each client kept the device identity it already had on disk — in Machine B's case one dating from April. Whatever produced the new device records, it was not the client rotating its stored device id.

The two `buddy-tokens.json` rewrites are 12.5 minutes apart and line up with neither the restarts nor the alerts.

### E. Both machines index their sessions under an identical path

The Windows session index lives at:

```
\claude-code-sessions\\\local_.json
```

The two installs put it in different places, because Machine B is the MSIX build:

```
Machine A: %APPDATA%\Claude\claude-code-sessions\
Machine B: %LOCALAPPDATA%\Packages\Claude_\LocalCache\Roaming\Claude\claude-code-sessions\
```

**Each machine has exactly one `` directory and one `` directory beneath it, and both segments are identical on the two machines.** Nothing in the index path distinguishes which machine wrote an entry.

**This is not for lack of a device identifier.** Each machine holds a distinct one, and neither value appears anywhere in the index path:

| | Machine A | Machine B |
|---|---|---|
| `ant-did` (base64-encoded UUID) | one UUID | a **different** UUID |
| device public key in `ant-device-registry.json` (`pk1:<32-byte hex>:`) | one key | a **different** key |
| key of the `ant-device-registry.json` map | `` | `` — the same |

So the client does maintain a per-device identity and the two installs are correctly distinguished by it. The session index path is built from the account-scoped map key (``) and ``, and ignores the device identity sitting next to it in the same directory. (`` also appears as a path segment under `scratch-workspaces\`, consistent with it being account-scoped. Actual values withheld here; available privately.)

Reconciling index entries against transcripts on each machine, joining on `cliSessionId` plus `priorCliSessionIds`:

| | Machine A | Machine B |
|---|---|---|
| Index entries / CLI session ids referenced | 7 / 8 | — / 18 |
| Transcripts in `.claude\projects\*\*.jsonl` | 8 | 20 |
| Orphaned transcripts (JSONL with no index entry) | **0** | **2** |
| Dangling index entries (no matching JSONL) | **0** | (not collected) |
| `` directories present | 1 | 1 (same UUID) |

**The transcripts involved in this incident were all indexed.** On Machine B every transcript of the affected project has a valid index entry, including all of the day's sessions, and they still left the project's sidebar group. The two orphans are unrelated — a different project, dated 2026-08-25 and 2026-08-26, ten days before this incident.

**Machine A displays sessions that exist in none of its index files.** Its index and transcripts agree perfectly, yet its sidebar lists 8 further sessions whose `cwd` values are Machine B paths. So the sidebar and the API read different stores: the API reflects the on-disk `local_*.json` index, and the sidebar shows something account-scoped from elsewhere (#31787's reporter concluded the list is read from the shared `IndexedDB\https_claude.ai_0.indexeddb.leveldb` store). Grepping that store for session titles returns nothing in plaintext — including titles of the machine's *own* sessions — so I could not inspect it to confirm.

## Impact

Low severity for data (nothing was lost), but the user-facing failure mode is bad: a day's work appears to have vanished from the machine it was done on and turns up in an unlabelled "Other" bucket on a different machine.

There is also a privacy dimension that does not bite here but would elsewhere: session titles from one machine are listed on another with no indication of origin. Same account and same person in my case, so no actual exposure — but the same mechanism across a work machine and a personal machine would surface one context's session titles in the other.

## Relationship to existing reports

#31787 describes the same end symptom on Windows — sessions vanishing from the sidebar while the JSONL files remain on disk — and identifies orphaned transcripts with no corresponding `local_*.json` entry, plus two competing directories under `claude-code-sessions\` on one machine (one from the VS Code extension, one from Desktop) sharing a single IndexedDB. It is closed as a duplicate and links #27752, #25524, #29154, #29373, #26452 and #9581.

This report shares the end symptom but **not the mechanism**. In #31787 the sessions that vanish are the ones with no index entry. Here every transcript of the affected project has a valid index entry on the machine that lost them, and they disappeared from the group anyway. The only orphans on that machine belong to a different project and predate the incident by ten days.

What I believe is not covered by the existing reports:

1. **Both machines' index paths are identical, segment for segment, even though the two machines carry distinct device identities.** #31787 describes the opposite problem — two competing directories on one machine. This is one path shared across two machines, built only from account-scoped identifiers while a per-device identifier sits unused in the same directory.
2. **Duplicate trusted-device registration** — one restart producing two device registrations per machine, while the client's stored device identity is untouched.
3. **Cross-machine bleed**, bidirectional, with no origin indicator.
4. **A clean index on the machine that receives the foreign sessions.** Machine A has zero orphans and zero dangling entries yet still displays 8 sessions that exist in none of its index files. A corrupted-local-index explanation does not cover this half of the behaviour.

## A hypothesis, offered as such

I could not establish a mechanism and am not asserting one.

The observation I would start from is that the index path is identical on both machines, so entries written by either install are indistinguishable by path — even though a per-device identifier exists and could have been used to scope them. Sidebar grouping, by contrast, is derived from `cwd`, which is machine-specific. A list resolved account-wide, combined with grouping that can only match locally, would produce exactly the observed split: foreign sessions land in an ungrouped "Other" bucket, and a project's own sessions can drop out of their group if the resolution picks the wrong side.

That is a shape, not a mechanism. It does not explain why the loss happened at that particular moment, and the fact that neither machine's stored device identity changed argues against the simplest version of any device-confusion story.

## One unverified observation

Three entries in Machine A's "Other" bucket correspond to sessions in Machine B's group for the affected project. One title matches exactly; two are worded differently for what appears to be the same session. Since titles are auto-generated (the index records carry a `titleSource` field), two independently generated titles for one session would suggest two separate records exist for it. I could not confirm this — the entries shown on Machine A have no local index files, so I have no session ids to compare.

## Available privately

Happy to provide, but not posting publicly:

- Full security-alert emails (IP addresses, cities, device strings, message ids)
- Machine hostnames and Windows usernames
- The `` / `` values and both device public keys
- Full session UUIDs for the affected transcripts
- Full `local_*.json` index entries and the reconciliation output for both machines

## How this was verified

Filesystem timestamps, file sizes, the index/transcript reconciliation and the session-management API results were read directly on Machine A. The same reconciliation, the directory listings and the index path were run on Machine B. Sidebar contents are from screenshots of both machines. Security-alert details are from the emails as received. The restart timing (1–2 minutes apart) is from recollection; everything else comes from timestamps or command output.

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Hướng nghiên cứu

Start by reproducing the two-machine Windows restart scenario and compare the local claude-code-sessions indexes with the sidebar data in IndexedDB\https_claude.ai_0.indexeddb.leveldb. Trace the trusted-device alerts alongside ant-did, ant-device-registry.json, and buddy-tokens.json. Done means one registration per existing device and sessions remain in the correct project group without cross-machine leakage.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
electron, powershell
Lĩnh vực
authentication, desktop, operating-systems
Loại issue
Lỗi
Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
30/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.