remote-control: 403 token expiry kills all active sessions instead of refreshing

Resolved 💬 8 comments Opened Apr 26, 2026 by Th0m45k Closed May 31, 2026

Description

claude remote-control fatally crashes and kills all active sessions when an OAuth token expires or rotates server-side, instead of refreshing the token and reconnecting gracefully.

When the token becomes stale, the process receives:

Error: Poll: Access denied (403): Account is no longer a member of the
organization associated with this token. Check your organization permissions.

This immediately kills every connected session (observed 12 sessions dying in under 1 second), the process exits, and when restarted (e.g. via launchd KeepAlive), it registers a new environment ID — orphaning all previous sessions. They appear as "inactive" in the Claude app and must be manually reopened.

Observed crash patterns

From ~/Library/Logs/claude-remote-control/daemon.log, the same fatal pattern occurs across multiple error types:

| Error | Sessions killed | Behavior |
|-------|----------------|----------|
| Poll: Access denied (403): Account is no longer a member... | 8–12 per incident | Token stale → all sessions die |
| EnvironmentInstance not found for session unknown | 13 sessions | Similar mass kill |
| Failed to refresh session token: timeout of 10000ms exceeded | cascading | Token refresh timeout → eventual crash |
| Persistent errors for 11 minutes, giving up | all | Gives up instead of backing off longer |

Total: 58 session failures across the log lifetime, in bursts that kill all sessions simultaneously.

Contrast with Desktop app behavior

The Claude Desktop app handles similar auth errors gracefully:

[sessions-bridge] Poll error, backing off: Poll: Failed with status 529:
Authentication service is temporarily unavailable. Retry the request.
[sessions-bridge] Backing off for 1000ms

The Desktop app backs off, retries, and reconnects without losing sessions. The remote-control CLI does not — it treats the same class of transient auth errors as fatal.

Impact

For users running remote-control as an always-on daemon (the intended use case), this means:

  • All active work sessions are killed without warning, multiple times per week
  • Sessions are orphaned (new environment ID on restart)
  • No notification that sessions died — user discovers hours later
  • Particularly disruptive for long-running sessions (dispatchers, monitoring)

Steps to reproduce

  1. Run claude remote-control --name "Test" --spawn same-dir as a persistent daemon (e.g. via launchd with KeepAlive)
  2. Create several sessions through the Claude app
  3. Wait for an OAuth token rotation/expiry (seems to happen every few days, sometimes multiple times per day)
  4. Observe all sessions die simultaneously with the 403 error

Expected behavior

  • remote-control should refresh the OAuth token on 403/401/529 errors (like the Desktop app does)
  • Transient auth errors should trigger exponential backoff + retry, not process exit
  • If the process does restart, it should attempt to reconnect to existing sessions rather than creating a new environment ID
  • At minimum: a 403 "organization" error from a stale token should not be treated as a permanent permission error

Environment

  • Claude Code: 2.1.100
  • macOS: 26.5 (Darwin 25.5.0 arm64)
  • Node: homebrew
  • Running via launchd LaunchAgent with KeepAlive: true, ThrottleInterval: 10

Additional error context

The error log also shows repeated Error: Remote Control is not yet enabled for your account. during rapid restart cycles — likely the same stale-token issue manifesting differently during the crash loop before a fresh token is obtained.

View original on GitHub ↗

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