Claude in Chrome: silent-reauth failure latches startupReauthState={terminal:true} with no cooldown, permanently killing the bridge until manual sign-out/sign-in

Status Open
Maintainer reply None cached
Activity 0 comments · opened Aug 19, 2026

Summary

After any full Chrome restart, the Claude in Chrome extension (v1.0.85) can enter a permanently parked state where it never re-establishes its bridge connection to the desktop app. Every mcp__claude-in-chrome__* call then fails with "No Chrome extension connected after discovery" indefinitely. The only user action that recovers it is a full sign-out and interactive sign-in in the extension panel. Toggling the extension, restarting Chrome, and restarting the desktop app all fail to recover it.

Environment

  • Windows 11 Pro 10.0.22631
  • Claude desktop app 1.32885.1.0 (MSIX / Microsoft Store), also reproduced on 1.32352.1.0
  • Claude in Chrome extension 1.0.85 (current store version)
  • Chrome stable, single profile

Mechanism (from reading the bundled worker code)

  1. The extension stores accessToken / refreshToken in chrome.storage.session, so every full Chrome restart wipes them.
  2. On cold start, the silent-reauth loop (bundle mcpPermissions-*.js, bridge-connect fn at offset ~806190; reauth state machine ~89600-92416) runs gated by the chrome.storage.session key startupReauthState.
  3. One account_mismatch/consent_required failure, or 3x interaction_required, latches {terminal:true} permanently — there is no cooldown, TTL, or retry.
  4. The 30-second bridge-keepalive alarm keeps firing but every invocation dies at the terminal-park gate before opening the WebSocket, so the extension never registers on wss://bridge.claudeusercontent.com/chrome/<accountUuid> again.
  5. No chrome.storage.onChanged listener wires auth-state changes to a reconnect. The only code path that unconditionally clears the park is the oauth_redirect external message handler (service worker bundle offset ~23088), i.e. a full interactive sign-in. A sign-in click that short-circuits on an existing cached session never reaches it.

App-side compounding factors

  • The desktop app treats "relay socket connected+authenticated, zero extension peers" as healthy and never re-dials or surfaces the condition; each tool call just times out after ~10s (NoExtensionConnectedError).
  • On every launch the app tries to refresh %APPDATA%\Claude\ChromeNativeHost\chrome-native-host.exe and, when the copy fails with EBUSY (stale host process holding the lock), logs the error and then logs "Native host sync complete" anyway, leaving a version-skewed native host after app updates.

Repro

  1. Be signed into the extension and working.
  2. Fully restart Chrome under conditions where the silent reauth fails once (e.g. claude.ai web session cookie invalidated/rotated).
  3. Bridge is now dead. Toggle extension: no recovery. Restart Chrome: no recovery (fresh cold-start reauth fails again or re-latches). Restart the desktop app: no recovery.
  4. Sign out in the panel, sign back in: instant recovery.

Suggested fixes

  • Give the terminal park a cooldown/TTL, or re-evaluate it on the existing keepalive alarm.
  • Trigger re-registration from a chrome.storage.onChanged auth-state listener so any successful auth (not only the oauth_redirect path) clears the park.
  • App-side: treat "authenticated but zero peers for N minutes" as a fault: re-dial, and surface it in the UI instead of only failing per-call.
  • Native host sync: don't log success after an EBUSY failure; retry after the stale process exits.

Impact

Multi-hour bridge outages that look identical to "extension not installed/signed in", resisting every intuitive recovery action. Diagnosed via process census, app logs (main.log), extension LevelDB state (mcpConnected=false with no subsequent writes despite alarms firing), and static reads of the minified bundles.

View original on GitHub ↗