Remote Control sessions disconnect over time and cannot be reconnected; /remote-control throws "failed to disconnect: Cannot read properties of undefined (reading 'session_url')"
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
- Open the Claude Code desktop app on Windows with
remoteControlAtStartupenabled, and start a named session. - Confirm in the Claude mobile app's Code tab that the session shows as Connected.
- Leave the session idle / continue working in other sessions for several hours.
- Check the mobile app again: the session now shows Disconnected.
- In the desktop app, in that session, run
/remote-controlto reconnect. - Observe the
session_urlerror. The session does not reconnect.
Expected
- A long-lived session stays connected to Remote Control, or reconnects automatically after a transient drop.
- Failing that,
/remote-controlreconnects a dropped session.
Actual
- Sessions drop silently after some hours, with no notification on the desktop side.
/remote-controlthrows 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
- Reconnect after a drop, automatically where possible — a long-lived session should re-establish Remote
Control rather than silently staying disconnected.
- Guard the disconnect path against stale or absent session state, and ensure a failed teardown does not
prevent a fresh connection from being established.
- Report state on success — "Remote Control connected" / "disconnected" — so users can distinguish a working
feature from a broken one.
- 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.*
3 Comments
I see this sometimes too. Remote-control overall where useful is very limited in its reliability for me.
Remote Control failed to disconnect: Cannot read properties of undefined (reading 'session_url')as described.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 900sWarmLifecyclepause. 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
bridgeSessionIdsand 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-controlthrows 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-controla 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 noremoteControlEnabledkey at all after the process died, so the toggle took the connect branch and never dereferencedsession_url. If your long-lived sessions retainremoteControlEnabled: truewhile the bridge is dead, the toggle attempts a disconnect first and readssession_urloff 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.
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.logshows 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: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: sessionlocal_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:
/remote-controlto do it manually.Happy to provide fuller logs if useful.