[BUG] Long-running `claude remote-control` server silently breaks after a CLI self-update — new sessions fail with EPERM while the server still reports connected
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
I run claude remote-control as a persistent server (a launchd LaunchAgent with RunAtLoad + KeepAlive) so I can start sessions on my Mac from the phone. claude-code auto-updated itself while that server was running, and from that point every new session spawned from the phone / claude.ai/code failed with An internal error occurred (EPERM).
The misleading part: the server kept reporting connected the whole time — green dot on the phone, a live ESTABLISHED :443 relay socket, launchctl print showing running, and the log printing Connected · Capacity 0/32. So it looks completely healthy but cannot spawn a single session, and nothing recovers on its own (KeepAlive never fires because the process never crashes or exits).
A plain restart of the server fixed it immediately, with no permission / Full Disk Access change of any kind — the key signal that this is the running process going stale across its own update, not a TCC / entitlement misconfiguration.
What Should Happen?
After the on-disk CLI changes, a long-running remote-control server should either:
- gracefully re-exec onto the new binary and keep spawning sessions; or
- at minimum, fail loudly and actionably (a clear message telling me to restart) instead of an opaque EPERM, and stop advertising itself as connected / healthy when it can no longer spawn sessions.
It should not keep showing a green / connected status on the phone while every new session dies.
Error Messages/Logs
The CLI self-updated at ~09:40 (the on-disk `package.json` mtime). The server process had started at 09:31 — before the update — and kept running. Both session attempts afterward failed:
[14:21:03] Session failed: error: An internal error occurred (EPERM) cse_...
[20:21:53] Session failed: error: An internal error occurred (EPERM) cse_...
Throughout, the server held a live ESTABLISHED :443 socket and logged `Connected` / `Capacity 0/32`. KeepAlive never intervened because the process never crashed or exited. The opaque EPERM line is the only error surfaced — no path or stack trace.
Steps to Reproduce
- Start
claude remote-controlas a long-lived server and leave it running (a launchdKeepAliveagent makes this easy, but a plain long-running terminal session reproduces it too). - While it is running, let the CLI update underneath it — auto-update,
claude update, ornpm i -g @anthropic-ai/claude-code@latest— so the on-disk@anthropic-ai/claude-codeinstall changes while the process keeps running. - From the Claude mobile app (or claude.ai/code), open the environment — it still shows connected / green — and start a new session.
- Result:
Session failed: error: An internal error occurred (EPERM). Repeats for every new session; the environment keeps advertising itself as connected. - Restart the server (
launchctl kickstart -k ..., or/remote-controlthen Disconnect then reconnect). Sessions work again immediately. No permission change was needed.
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.185 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Environment: macOS (Darwin 25.5.0), Apple Silicon; claude-code 2.1.185 installed as an npm global under nvm (node v22.22.3); logged in via claude.ai subscription; spawn mode same-dir; server run as a persistent launchd LaunchAgent (RunAtLoad + KeepAlive).
Hypothesised cause (not confirmed): the self-updater rewrites the on-disk install while the server keeps executing pre-update code in memory; session spawning then crosses the old-process / new-on-disk-install boundary and fails with EPERM. Because a plain restart (no FDA / permission change) fully resolves it, this points to a stale process running across its own update rather than a permissions problem.
Impact: affects anyone running remote-control as a persistent server — the intended setup for always-available phone access — and auto-update is on by default, so the collision is reachable with no unusual configuration. The failure is silent: the device shows green and connected, but every session fails, which reads like an account or network problem rather than a stale server.
Workaround: restart the server after any CLI update. I run a 10-minute watchdog that compares the on-disk install's package.json mtime against the server process start time and kickstart -ks onto the new binary when the install is newer (deferring while a session is active so it never kills live work).
Related:
- Sibling reliability bug (network reconnect, not update): #34255 (silent stale-but-alive on connection drop); umbrella #33041 — same family of 'server looks healthy but cannot serve, no self-recovery'.
- Same class — CLI self-update silently breaking a long-lived integration: #69546 (Chrome native host dies on every version bump).
- Adjacent EPERM / after-update reports: #48238 (
/remote-controlinit fails after updating), #48244 (spawn EPERM).
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗