[BUG] Desktop + Remote Control: forked session cannot reconnect after disconnect; `/teleport` inside a `--resume`d session writes a root entry (parentUuid: null) and severs the transcript chain

Status Open
Reported on v2.1.284
Maintainer reply None cached
Activity 0 comments · opened Sep 29, 2026

Version: Claude Code 2.1.284, Desktop app (macOS, Darwin 24.6.0), Remote Control to phone
Model in session: claude-sonnet-4-5-20250929

Summary

Two related problems observed on one session (a fork created from the web UI while the parent ran locally under Remote Control):

  1. Forked session is unrecoverable from the Desktop app after a disconnect. The fork got its own bridge ID. When the connection dropped overnight, the Desktop app showed the fork as "Remote Control disconnected" and never spawned a new local CLI process for it. The parent session and all other sessions reconnected fine. The fork's local transcript (~/.claude/projects/<proj>/<fork-id>.jsonl) was complete the whole time. claude --resume <fork-id> in a terminal worked, but the app then lists it as a new session (new bridge ID) while the old entry stays dead forever.
  1. /teleport inside a --resumed session destroys the conversation context. After claude --resume <fork-id> and /remote-control (both fine), running /teleport in that session printed "Session resumed successfully" and appended a system/local_command row with parentUuid: null to the same JSONL. Because --resume reconstructs context by walking parentUuid from the last row, every subsequent turn only saw the rows after that new root. The model's context dropped from ~117k tokens to ~40k (system prompt only). The terminal still rendered the whole file, so the UI looked fine while the model had amnesia.

Likely related: #95873 (Remote Control sessions have 0 teleport-events, so --teleport yields an empty session), #94836 (--teleport restores only first turn), #96628 (a parentUuid pointing at a never-written row makes --resume lose everything before it), #95925 / #97981 (dead entries in session lists).

Steps to reproduce

  1. Start a local session in the Desktop app with Remote Control enabled. Chat for a while.
  2. From claude.ai/code on the phone, fork the session. Continue chatting in the fork (it runs locally; a second JSONL appears).
  3. Let the connection drop (sleep / network). Reopen the Desktop app.

→ Fork entry shows "Remote Control getrennt" and never recovers. Parent recovers.

  1. In a terminal: claude --resume <fork-id> → session loads, context intact.
  2. In that session: /remote-control → works, new bridge ID.
  3. In that session: /teleport → "Session resumed successfully".
  4. Send a message and ask the model what it remembers.

→ Only the messages after step 6. Everything before is invisible to the model but still visible in the terminal transcript.

Evidence (from the JSONL)

row 314  system/bridge_status   parentUuid: 316eb440…   "/remote-control is active"
row 315  system/local_command   parentUuid: null        "<command-name>/teleport</command-name>"   ← new root
row 316  system/local_command   parentUuid: ea98fff8…   "<local-command-stdout>Session resumed successfully</local-command-stdout>"
row 320  user                   parentUuid: 83aeb767…   (first message after teleport)

API usage on the assistant turns (from message.usage):

| turn | cache_read | cache_creation | total context |
|---|---|---|---|
| last turn before disconnect | 116,671 | 1,078 | ~117k |
| first turn after /teleport | 0 | 40,412 | ~40k |
| first turn after manual fix (below) | 28,690 | 102,371 | ~131k |

Workaround that restored the context

Exit the session, set parentUuid of the /teleport row to the uuid of the preceding row (the bridge_status row), claude --resume again. One field. Full context returned (131k tokens). The model then still claimed it saw nothing, because its own pre-fix answers ("I only see two messages") were the most recent turns in its context; asking it to quote the first message of the session made it look and confirm it had everything.

Expected

  • A forked session should be resumable from the Desktop app after a disconnect, same as its parent (or at least the dead entry should be reconciled with the resumed one, since both point at the same local JSONL).
  • /teleport inside a live session should either refuse when the session already has local history, or link its marker row to the previous leaf instead of writing a new root. Writing a parentUuid: null row into an existing transcript silently orphans everything before it.
  • If a transcript contains orphaned rows before the current root, --resume should warn.

View original on GitHub ↗