62 lines
2.4 KiB
Markdown
62 lines
2.4 KiB
Markdown
|
|
# Cross-account session resume — bug analysis
|
||
|
|
|
||
|
|
## Symptom
|
||
|
|
|
||
|
|
When Claude Code is relaunched under a different Anthropic account
|
||
|
|
(different `~/.claude/` directory), invoking `claude --resume <id>`
|
||
|
|
fails with a "session not found" error even though the session
|
||
|
|
transcript JSONL still exists on disk. The new account has no record of
|
||
|
|
the session id because Claude Code tracks resumable sessions per-account
|
||
|
|
in its local state store.
|
||
|
|
|
||
|
|
Upstream report: Claude Code issue **#16103** (cross-account resume).
|
||
|
|
|
||
|
|
## Consequence for claude-failover
|
||
|
|
|
||
|
|
Naïve account swap (stop sessions on account A, start on account B
|
||
|
|
pointing at a different `~/.claude/projects/` tree) loses every running
|
||
|
|
session. That would defeat the purpose of failover — we would be forced
|
||
|
|
to kill in-flight tasks on every quota boundary.
|
||
|
|
|
||
|
|
## Solution — shared projects tree via symlink
|
||
|
|
|
||
|
|
The `projects/` subtree under `~/.claude/` is where the session
|
||
|
|
transcripts live. We keep a single canonical copy at
|
||
|
|
`/home/ubuntu/.claude-projects-shared/` and symlink each account's
|
||
|
|
`~/.claude/projects` to it:
|
||
|
|
|
||
|
|
```
|
||
|
|
/home/ubuntu/.claude-compte1/projects -> /home/ubuntu/.claude-projects-shared/
|
||
|
|
/home/ubuntu/.claude-compte2/projects -> /home/ubuntu/.claude-projects-shared/
|
||
|
|
```
|
||
|
|
|
||
|
|
With this layout:
|
||
|
|
|
||
|
|
- Account A records session `S1` while running. Its transcript lands in
|
||
|
|
the shared directory.
|
||
|
|
- On swap, account B's Claude Code process starts with its own
|
||
|
|
credentials but sees the same `projects/` tree.
|
||
|
|
- `claude --resume S1` finds the transcript and replays it.
|
||
|
|
|
||
|
|
The per-account state that is **not** shared — credentials, telemetry
|
||
|
|
cache, statsig flags — stays isolated because only `projects/` is
|
||
|
|
symlinked, not the whole `~/.claude`.
|
||
|
|
|
||
|
|
## Validation checklist (for implementers)
|
||
|
|
|
||
|
|
- [ ] `claude --resume` succeeds across accounts when `projects/` is
|
||
|
|
symlinked
|
||
|
|
- [ ] No transcript corruption when both accounts write concurrently
|
||
|
|
(they cannot — only one account is active at a time)
|
||
|
|
- [ ] Permissions on the shared dir allow the daemon user to read/write
|
||
|
|
- [ ] Backup strategy in place before first production failover
|
||
|
|
|
||
|
|
## Open questions
|
||
|
|
|
||
|
|
- Does Claude Code cache the session id in a per-account index that
|
||
|
|
needs to be pre-populated? If yes, the account-switcher must write a
|
||
|
|
small stub entry there on swap.
|
||
|
|
- Does a running session survive the HOME symlink flip, or must it be
|
||
|
|
restarted? Current assumption: restart is required, hence the
|
||
|
|
checkpoint goroutine.
|