[BUG] remote-control: transient supervisor exits (poll 401 / memory pressure) permanently orphan every attached session — environment survives a 2s restart but not a 10s one
Environment
@anthropic-ai/claude-code: 2.1.232 at the time of both incidents (native binary, linux-x64); currently on 2.1.251- Node.js v26.5.0, Ubuntu 26.04 LTS, x86_64, 30 GiB RAM + 7 GiB swap
- Consumption path: a long-lived
claude rc --name <name> --permission-mode acceptEditssupervisor run as a systemd user service (Restart=always) so that phone/browser (claude.ai/code) clients can attach to a persistent server-side environment. Sessions are attached and detached over days.
Summary
Two different transient conditions each caused the remote-control supervisor to exit, and in both cases the restart came up with a new environment ID, permanently orphaning every previously attached session (the mobile app shows them as "environment deleted"; transcripts are readable but not resumable).
The common factor appears to be how long the supervisor is absent, not why it left:
| supervisor gap | environment after restart | n |
|---|---|---|
| 1–3 s (clean systemctl restart) | preserved | ~40 observed over 9 days |
| 10–11 s (crash → Restart=always) | new environment, all sessions unrecoverable | 2 observed |
If that reading is right, a modest grace period on the server side would eliminate the user-visible damage from both incidents below, independent of their root causes.
---
Incident A — a poll-time 401 tears down every session; an immediate restart with the same on-disk credentials succeeds
Supervisor uptime 1 d 0 h 0 min; cgroup memory peak 25.3 GiB, swap peak 574.7 MiB.
18:57:40 Error: Poll: Authentication failed (401): OAuth access token has expired.
Re-authenticate to continue.. Remote Control is only available with claude.ai
subscriptions. Please use `/login` to sign in with your claude.ai account.
18:57:40 Shutting down 10 active session(s)…
18:57:43 systemd: Consumed 1h 10min CPU over 1d, 25.3G memory peak, 574.7M swap peak.
18:57:54 systemd: Scheduled restart job, restart counter is at 3.
18:57:55 Connecting …
18:57:58 Attached
What is notable:
- No human re-authentication happened. systemd restarted the process 14 s later with the same credentials file on disk, and it attached and worked normally from then on. So the credentials were refreshable; the running process appears to have been holding a token captured earlier with no reload/refresh path on the poll loop. (Inference from the restart succeeding — I have not read the client code.)
- The supervisor's response to one failed poll was to shut down all 10 active sessions and exit.
- Since 2026-08-20 I have logged 23 occasions where a running supervisor crossed its token-expiry timestamp with no error at all, so refresh evidently does work in the normal path. That makes this a race/edge case rather than the norm — but the blast radius when it does fire is total.
Expected: a 401 on the poll loop should trigger a credential reload/refresh and retry before any session teardown; failing that, sessions should survive a supervisor restart.
---
Incident B — a supervisor that is running but memory-starved is declared "offline" and the server garbage-collects its environment
Supervisor uptime 3 d 7 h; cgroup memory peak 24.2 GiB, swap peak 2.4 GiB, on a 30 GiB host.
18:57:24 14 sessions ended while this machine was offline — the environment was
cleaned up on the server and can't be resumed.
18:57:24 Run `claude remote-control` to start a fresh environment.
18:57:24 Shutting down 10 active session(s)…
18:57:27 systemd: Consumed 5d 1h CPU over 3d 6h 58min, 24.2G memory peak, 2.4G swap peak.
18:57:37 systemd: Scheduled restart job, restart counter is at 2.
The machine was not offline — the supervisor process was alive and had been logging continuously (3,558 journal lines in the preceding two hours). It was thrashing: 24.2 GiB resident plus 2.4 GiB of swap on a 30 GiB host. The most plausible reading is that it missed its poll deadline for long enough that the server considered the environment abandoned and reclaimed it, costing 14 sessions.
A separate earlier generation was killed outright by the kernel OOM killer at a 28.2 GiB peak, so the growth is real and unbounded, not a metering artifact.
Expected: a supervisor that reconnects should be able to re-attach to its environment rather than being told it was cleaned up; and/or the "offline" determination should tolerate a slow-but-alive supervisor.
The underlying memory growth looks related to the already-open #78778 and #85639 (supervisor not reaping per-session child processes). I am not claiming the same root cause — I did not capture per-child process evidence during the growth window — but the resulting host-level pressure is what triggered Incident B.
---
Impact
For a persistent server-hosted remote-control setup, each of these events loses all in-flight work and makes every session in the mobile app's list permanently unresumable. Between 2026-08-15 and 2026-08-19 this happened three times.
Workaround deployed
A host-side watchdog that pre-emptively restarts the supervisor at quiet moments, based on memory and uptime, so it never reaches the pressure levels above. Because clean restarts complete in 1–3 s the environment survives, and attached sessions are messaged to resume. This masks the problem rather than fixing it — and it means I cannot easily reproduce Incidents A or B again on demand.
Question
Is there a documented environment-retention grace period after a supervisor disconnects, and is it configurable? Raising it (or allowing an explicit re-attach by environment ID on startup) would make both failure modes non-destructive without needing to fix either root cause first.