remoteControlAtStartup silently no-ops when OAuth is unhealthy at session start — never re-evaluated, session invisible to ListAgents for its whole lifetime

Status Open
Reported on v2.1.241
Maintainer reply None cached
Activity 4 comments · opened Aug 23, 2026

Environment

  • Claude Code 2.1.241 (CLI, terminal session — not desktop-hosted)
  • macOS (Tahoe 26.x)
  • remoteControlAtStartup: true in ~/.claude/settings.json
  • Subscription auth (OAuth via keychain)

Summary

Remote Control startup registration appears to be evaluated exactly once, at session start, with no retry and no user-visible signal on failure. If the account's OAuth token is expired/unrefreshable at that moment, the session runs its entire lifetime unregistered: ListAgents inside it returns "No reachable agents", and the session never appears on the account's roster from any other session — while the flag sits at true and nothing reports that it did nothing.

Repro (as observed)

  1. Machine A has a broken OAuth state at session start (in our case: a blank duplicate Claude Code-credentials keychain entry shadowing the real one, so headless refresh failed with OAuth session expired and could not be refreshed).
  2. Start an interactive CLI session on machine A with remoteControlAtStartup: true.
  3. Later, fix the OAuth problem (delete the shadowing entry, claude login succeeds; claude -p auths cleanly).
  4. The already-running session remains unregistered indefinitely: its ListAgents still says "No reachable agents"; other sessions on the account never see it.

Evidence it's the one-shot registration, not the capability

  • A fresh claude -p probe on machine A (post-auth-fix) enumerates local peers fine.
  • Manually toggling Remote Control on in the affected session (no restart) registered it within seconds — it immediately appeared on another machine's ListAgents roster as Remote Control · idle and received a cross-session message. So everything works except the silent, never-retried startup path.

Expected

Either (a) retry/re-evaluate RC registration when auth becomes healthy (or at least on a timer / on ListAgents use), or (b) surface a visible warning that remoteControlAtStartup failed and how to recover (/remote-control). Silent permanent no-op with the flag set to true is the worst of both.

Related (same one-shot-never-re-evaluated shape, different triggers)

  • #77282 (eligibility check races profile fetch, never re-evaluated)
  • #82462 (registration lost after /clear, never re-established)
  • #78730 / #85086 / #84793 (desktop relaunch/resume variants)

A general "re-evaluate RC registration when its preconditions change" fix would likely close this whole cluster.

🤖 Filed via Claude Code

View original on GitHub ↗

4 Comments

wslyfrnkln · 7 days ago

Additional diagnostics from the affected machine (may sharpen the root cause beyond the OAuth-at-startup trigger):

  • ~/.claude/remote-settings.json was {} — freshly written during the dead session. So the RC subsystem initialized, wrote its settings file, and connected to nothing.
  • remoteControlAtStartup does not appear in claude config list output on 2.1.241, despite being set in settings.json and (on a second machine, same version) apparently working.
  • Manually toggling Remote Control on in the affected session registered the endpoint within seconds — cross-machine ListAgents showed it as Remote Control · idle and two-way messaging worked immediately.

So the failure signature to look for: flag set in settings.json + remote-settings.json written as {} + session invisible on the roster, no error anywhere. Recovery: manual toggle, no restart needed.

wslyfrnkln · 7 days ago

Confirming which precondition actually fired, after cross-checking both machines: unhealthy OAuth at session launch — not a hypothetical. The affected session launched while the account's OAuth token could not be refreshed (keychain issue); RC startup registration silently no-oped as a downstream casualty. The empty remote-settings.json was the symptom written by that failed initialization, not an independent config problem — which is exactly the misdirection this bug produces: the operator spent most of a session chasing a config/bridge problem that was an auth problem wearing a config costume. The endpoint registering instantly on manual toggle happened after auth had been repaired — auth-green was the enabling condition, not the toggle alone.

Suggested framing for the fix: when RC startup registration fails, say why (auth vs. eligibility vs. transport) — a one-line stderr note naming the failed precondition would have saved the whole diagnostic detour, even before any retry logic.

wslyfrnkln · 7 days ago

Cross-machine differential that narrows this further:

  • Working machine (registrations happen at startup, many RC sessions on the roster over time): remoteControlAtStartup: true in settings.json and no ~/.claude/remote-settings.json at all — the file simply doesn't exist.
  • Affected machine: same flag, same version (2.1.241), but remote-settings.json exists containing exactly {} — and startup registration silently no-ops. After a successful manual toggle (registration live, cross-machine messaging working), the file still contains {} (mtime unchanged) — so a successful registration does not write it either, and auth health is independent of the empty file (auth is green now; file still empty).

Working hypothesis from the differential: an empty-but-present remote-settings.json poisons the startup path (parse {} → no config → skip), while an absent file falls through to defaults and works. If so the earlier OAuth correlation was a second, independent trigger — and registration state looks per-session/server-side, with nothing durable persisted locally by design.

Repro suggestion for whoever picks this up: create remote-settings.json with {} on a working install and see if the startup flag stops registering.

wslyfrnkln · 7 days ago

[Amended — the original claim in this comment was overstated and is corrected below.]

  1. ~~The subsystem actively WRITES the empty file~~ — retracted after further testing. The three mtime bumps on remote-settings.json (content {} throughout) all occurred while the file existed. After removing the file and doing a full session launch + re-auth + RC enable, it was NOT recreated. So the writer only rewrites an existing file; it never creates one. Removal is durable, and the earlier inference ("the real defect is the writer, removal is non-durable") was wrong.
  1. Current best-supported picture: an empty-but-present remote-settings.json correlates with the silent startup no-op, an absent file matches the working machine's state, and nothing recreates the file once removed. The decisive cell — does remoteControlAtStartup register a fresh session with the file absent and no manual RC toggle — remains untested (the launch we ran was contaminated by a manual toggle) and will be reported if/when we run it cleanly.
  1. Unchanged: explicit --remote-control <name> on the exec line registers reliably — the working operator-side mitigation.