[BUG] Remote Control: after a host reboot the environment re-registers with the same ID but drops all pre-existing sessions — claude.ai/code shows them, sending fails with "session not found", transcripts intact on disk

Status Open
Reported on v2.1.226
Maintainer reply None cached
Activity 2 comments · opened Aug 8, 2026

Summary

I run claude remote-control as a long-lived systemd user service on a GCP VM and do all my work from claude.ai/code in the browser — I never drive these sessions from the terminal.

The VM is power-cycled daily by a scheduled auto-stop. On boot, the RC server comes back and re-registers with the same environment ID (it's persisted locally), but the environment's session count resets: Capacity: 14/32 before the stop, 0/321/32 after. The 14 sessions that existed on that environment are never re-attached.

From the web UI those 14 sessions still appear in the session list and open fine — full history renders. But sending a message fails with a session not found error. There is no way to resume them from the web. Their transcripts are intact on disk under ~/.claude/projects/<dir>/*.jsonl, complete with bridge-session records.

So the work is not lost, but it is unreachable through the only interface I use, and the failure is undiscoverable until the user types a message into what looks like a healthy conversation.

Environment

  • Claude Code 2.1.226 (logs don't stamp a version; the capture below is from the build installed on 2026-08-06, which may be marginally older)
  • Ubuntu 22.04.5 LTS, kernel 6.8.0-1064-gcp, GCE VM
  • claude remote-control (no flags), wrapped in a systemd user unit with Restart=always, WorkingDirectory = the repo root
  • Client: claude.ai/code in a desktop browser. No mobile app involved.

Reproduction

  1. Run claude remote-control as a supervised long-lived service in directory D.
  2. From claude.ai/code, work in several sessions on that environment until the TUI reports e.g. Capacity: 14/32.
  3. Hard-stop the host machine (scheduled VM stop / power off — not a graceful claude exit).
  4. Boot the host. The unit restarts claude remote-control.
  5. The TUI reports the same https://claude.ai/code?environment=env_<REDACTED> URL, but Capacity: 0/32, then 1/32 once a fresh session is pre-created.
  6. In claude.ai/code, open any of the 14 pre-existing sessions. History renders. Send a message → "session not found". The session is permanently unusable from the web.

Expected

On re-registration, an environment should re-attach — or be able to lazily attach on demand — the sessions that belong to it and whose transcripts are present on the host. Failing that, the web UI should mark such sessions as unreachable before the user types, and offer an explicit rehydrate/resume action.

Actual

The sessions are orphaned server-side. Recovery is entirely manual and requires shell access to the host: the transcript filename is an unrelated UUID with no relationship to the cse_/session_ ID, so finding the right file means grepping ~/.claude/ (via ~/.claude/sessions/<pid>.json for live processes, or ~/.claude/jobs/*/state.json for daemon jobs). claude --resume <uuid> in a terminal can rehydrate it as a local session, but that does not restore the web thread.

Evidence

Journal from the 2026-08-06 cycle (IDs redacted):

# before the stop
Aug 06 04:55:00  Capacity: 14/32 · New sessions will be created in the current directory
Aug 06 04:55:00  <14 session titles listed, 2 marked "Attached">
Aug 06 04:55:00  Continue coding ... https://claude.ai/code?environment=env_<REDACTED>

# VM powered off 05:02, booted 08:28
Aug 06 08:29:42  systemd[...]: Started Claude Code Remote Control (...).
Aug 06 08:30:11  Capacity: 0/32 · New sessions will be created in the current directory
Aug 06 08:30:11  Continue coding ... https://claude.ai/code?environment=env_<REDACTED>   <- same env ID
Aug 06 08:30:12  Capacity: 1/32
Aug 06 08:30:12  session_<REDACTED_NEW> Attached                                          <- freshly pre-created

Notably, there are no 404s and no worker registration failed lines anywhere in 14 days of RC logs (~800 MB) — the only error in that window is a single Session failed: Process exited with error cse_<REDACTED> on Aug 5, unrelated. The environment itself is healthy: new sessions created after the reboot work normally.

Impact

This happens on every host stop, which for me is daily. Multi-hour sessions across several worktrees are stranded each time. Because the thread opens and renders normally, the user discovers the loss only after composing and sending a message.

Why this isn't a duplicate

  • #77372 / #80473 (ghost sessions cause permanent 404s) — no 404s here, and the environment is not broken: new sessions work fine.
  • #78695 / #76811 / #71532 (stale environments accumulate / stay green / duplicate) — the environment is a single, healthy, correctly-reused registration. The problem is the sessions inside it.
  • #68606 (closed as stale/not planned) — describes the same restart, but frames it as "which session gets pre-created" and accepts CLI claude --resume as the recovery path. That's no help for a browser-only workflow, and it says nothing about the N stranded sessions.
  • #80311 (transient disconnect kills sessions permanently) — closest in spirit, but there the client keeps showing sessions as alive and silently swallows messages; here an explicit error is returned.
  • #83477 (import local CLI sessions into the session registry) — the inverse direction: backfilling never-bridged sessions, not re-attaching sessions the environment already owned.

Request

Any one of these would resolve it, in descending order of preference:

  1. Re-attach on re-registration — when an environment re-registers with a known ID, restore the sessions it owned whose transcripts exist on the host.
  2. Lazy attach — when the web sends a message to a session belonging to a registered environment, spawn a worker with --resume <uuid> on demand instead of returning session not found.
  3. At minimum, make it recoverable and visible — mark unreachable sessions in the session list before the user types, and include the host-local transcript UUID/path in the error so recovery isn't a grep hunt.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗