Remote Control sessions disconnect over time and cannot be reconnected; /remote-control throws "failed to disconnect: Cannot read properties of undefined (reading 'session_url')"

Status Open
Reported on v2.1.220
Maintainer reply None cached
Activity 3 comments · opened Aug 1, 2026

Environment

  • Platform: Windows 11, Claude Code desktop app
  • Version: 2.1.220 (also reproduced on 2.1.218)
  • Setup: several long-lived named sessions ("lanes"), each in its own git worktree, kept open for days
  • Setting in ~/.claude/settings.json: "remoteControlAtStartup": true

Summary

This is not a "Remote Control never works" report. Connection works. The defect is that sessions drop out of
Remote Control over time and cannot be brought back.

Observed state in the Claude mobile app's Code tab, at a single moment:

| Session | State | Last activity |
|---|---|---|
| Claude | Connected | 12m |
| Testing | Connected | 4h |
| Testing | Disconnected | 6h |
| Build | Disconnected | 10h |
| Automated Tasks | Disconnected | 1d |
| Testing | Disconnected | 1d |
| Decision & Planning | Disconnected | — |

The pattern is consistent: recently active sessions are connected; older ones have all dropped. The user did
not disconnect any of them.

The compounding fault: /remote-control — the obvious way to reconnect a dropped session — does not
reconnect. It throws:

Remote Control failed to disconnect: Cannot read properties of undefined (reading 'session_url')

So once a session drops, there is no way to restore it short of restarting the session entirely.

Steps to reproduce

  1. Open the Claude Code desktop app on Windows with remoteControlAtStartup enabled, and start a named session.
  2. Confirm in the Claude mobile app's Code tab that the session shows as Connected.
  3. Leave the session idle / continue working in other sessions for several hours.
  4. Check the mobile app again: the session now shows Disconnected.
  5. In the desktop app, in that session, run /remote-control to reconnect.
  6. Observe the session_url error. The session does not reconnect.

Expected

  1. A long-lived session stays connected to Remote Control, or reconnects automatically after a transient drop.
  2. Failing that, /remote-control reconnects a dropped session.

Actual

  1. Sessions drop silently after some hours, with no notification on the desktop side.
  2. /remote-control throws and does not reconnect. The session is stranded as Disconnected.

Likely cause (inferred from the error text and the observed pattern)

The toggle appears to take the disconnect branch when it finds existing-but-stale connection state, then
reads session_url from an object that no longer exists, and throws — never reaching the reconnect logic. That
would explain why the error says "failed to disconnect" when the user's intent was to connect, and why it is
reproducible specifically on sessions that were once connected and have since dropped.

Impact

The user runs several long-lived lanes and relies on Remote Control to check on them and answer permission
prompts away from the desk. In practice most sessions are unreachable most of the time: they connect, drop within
hours, and cannot be restored. The feature is therefore unreliable for its main purpose — long-running sessions
are exactly the ones that drop, and exactly the ones the user most needs to reach remotely.

A secondary cost: because the error says "failed to disconnect" and no success state is ever reported, the user
spent considerable time restarting the app, updating from 2.1.218 to 2.1.220, and changing settings, believing
the feature to be wholly broken rather than dropping.

Suggested fix

  1. Reconnect after a drop, automatically where possible — a long-lived session should re-establish Remote

Control rather than silently staying disconnected.

  1. Guard the disconnect path against stale or absent session state, and ensure a failed teardown does not

prevent a fresh connection from being established.

  1. Report state on success — "Remote Control connected" / "disconnected" — so users can distinguish a working

feature from a broken one.

  1. Surface the drop on the desktop side. At present a session's Remote Control connection can lapse with no

indication whatsoever in the desktop app; the user only discovers it by checking the phone.

---

*Screenshots available: the desktop error, and the mobile Code tab showing the mix of Connected and Disconnected
sessions with their ages.*

View original on GitHub ↗

3 Comments

twhitmorenz · 29 days ago

I see this sometimes too. Remote-control overall where useful is very limited in its reliability for me.

  • Remote-control never connects by default, even though I have that set.
  • Remote-control drops if I ever /clear. So from the remote I always have to use /compact insteda.
  • Remote-control mostly connects successfully... if I wait for the previous prompt to finish and baby the request through. If I don't, it often might not.
  • Remote control will stay connected for several hours... but then fall off. And it gets into the state d-a-ryan describes above where it's not connected, but I can't reconnect it, and just see the useless error message Remote Control failed to disconnect: Cannot read properties of undefined (reading 'session_url') as described.
Smedis · 28 days ago

The duplicate-name rows in your table ("Testing / Connected / 4h" above "Testing / Disconnected / 6h") have a concrete mechanism, and this issue looks like two separable faults.

1. Why sessions drop — not gradual expiry. A session loses its bridge when the Claude Code process hosting it ends, most commonly a Desktop app relaunch including the automatic relaunch after an app update. It is not the idle timeout: pauseSession() returns early for sessions with a live bridge (Skipping pause for session … - remote control is active), so they are exempt from the 900s WarmLifecycle pause. On resume the process respawns, but the auto-enable predicate is never evaluated — it runs only at session creation — so nothing re-arms. Log evidence in #82140; see also #78730 and #78564. Your "recently active sessions are connected; older ones have all dropped" pattern is exactly what that produces: the older a session, the likelier it has been through a relaunch.

2. Why the duplicate rows appear. When a dropped session is re-armed, the new bridge handle is appended to bridgeSessionIds and the dead one is never retired, so the mobile list gains a second row rather than updating the existing one. That is the source of your two "Testing" rows. Filed as #83378.

3. Why /remote-control throws for you but not for me. On Claude Desktop 1.24012.9 / Claude Code 2.1.219 (Windows 11), on a session that had shown Disconnected since the previous day: I sent an ordinary message in the session and got a normal response, then ran /remote-control a few minutes later. It reconnected cleanly and restored full history on mobile.

The likely difference is which branch the toggle takes. It toggles on remoteControlEnabled, and the error text you quote is from the disconnect path (#77915, #78336). In my case the persisted session record had no remoteControlEnabled key at all after the process died, so the toggle took the connect branch and never dereferenced session_url. If your long-lived sessions retain remoteControlEnabled: true while the bridge is dead, the toggle attempts a disconnect first and reads session_url off a result that is gone.

If that holds, "cannot be reconnected" is a consequence of the missing null guard rather than a separate reconnect failure — meaning #77915's guard would fix the reconnect path here too. Worth splitting so that half does not block on the "drops over time" half.

charlesNetvigie · 18 days ago

Confirming on macOS (Darwin 25.3.0, Apple Silicon), Claude Code desktop app, CLI 2.1.227, "remoteControlAtStartup": true, claude.ai OAuth. Same pattern: sessions created days ago were remotely controllable at first, then dropped off the mobile app's device list one by one; only freshly created sessions show up. The mobile app reports "no devices connected recently" while several of those sessions are still running in the Desktop app.

One data point that complements @Smedis's process-restart mechanism: the presence can also be lost without any app relaunch. ~/Library/Logs/Claude/main.log shows the app running continuously (no gap in hourly updater checks from Aug 9 through Aug 11), yet on Aug 9 the bridge entered a reconnect loop it never recovered from:

2026-08-09 08:25:31 [info] [remote-control] bridge_state: reconnecting — presence heartbeats failing — reconnecting
2026-08-09 08:26:03 [info] [remote-control] bridge_state: reconnecting — presence recovery failed — retrying
2026-08-09 08:26:33 [info] [remote-control] bridge_state: reconnecting — presence heartbeats failing — reconnecting
2026-08-09 08:27:05 [info] [remote-control] bridge_state: reconnecting — presence recovery failed — retrying

After that, the affected sessions never re-registered. Two months of logs confirm what Smedis inferred: Enabling remote control for session <id> appears exactly once per session, at creation — never on resume, and notably not even when the user interacts with the session again. Example: session local_49206ef3-… was enabled at creation on Aug 5, dropped at some point, was actively used again on Aug 11 at 23:24 (visible SDK activity in the log), and no re-enable or bridge reconnect was attempted for it.

So the two faults compound on macOS too:

  1. presence loss can happen in-process (heartbeat/recovery failure), not only via app relaunch;
  2. nothing ever re-arms remote control for an existing session — the auto-enable predicate only runs at session creation, and the Desktop app has no equivalent of the CLI's /remote-control to do it manually.

Happy to provide fuller logs if useful.