Claude in Chrome: WebSocket bridge pairing fails silently on Windows despite all prerequisites met

Resolved 💬 3 comments Opened Feb 11, 2026 by NotMyself Closed Feb 11, 2026

Environment

  • OS: Windows 11 Pro 10.0.26200
  • Claude Code: v2.1.39
  • Chrome Extension: v1.0.49 (ID: fcoeoabgfenejglbffodgkkbkcdhcgfn)
  • Chrome: latest stable
  • Account: Claude Max subscription

Problem

mcp__claude-in-chrome__tabs_context_mcp always returns "Browser extension is not connected" on Windows. After 6 debugging sessions, the root cause is that the WebSocket bridge (wss://bridge.claudeusercontent.com) never pairs the desktop (Claude Code) and Chrome extension sides, even though both connect successfully.

What Works

  • Chrome extension connects to wss://bridge.claudeusercontent.com/chrome/{accountUuid} and receives {"type":"waiting"}
  • Claude Code main process establishes 3+ bridge connections to 160.79.104.10:443
  • Extension OAuth token is valid, feature flag chrome_ext_bridge_enabled is enabled
  • Account UUID resolves correctly via /api/oauth/profile
  • Extension sends correct connect message: {"type":"connect","client_type":"chrome-extension","device_id":"...","os_platform":"Windows","oauth_token":"..."}

What Fails

The bridge server returns {"type":"stats","desktopConnected":true,"addinCount":0} — it never counts the Chrome extension as a valid addin. Both sides remain in "waiting" state indefinitely. No "paired" or "peer_connected" messages are ever received.

Root Causes Found

1. oauthAccount.accountUuid never populated in Claude Code

B$().oauthAccount?.accountUuid (used as user_id in the bridge connect message) is only populated during token refresh via Zn$(). If the token in .credentials.json hasn't expired, refresh never triggers, and getUserId() returns undefined. The bridge can't match a desktop with user_id: undefined to a Chrome extension at /chrome/{uuid}.

Setting expiresAt: 0 in .credentials.json and restarting with claude --chrome causes the new session to make 25+ bridge connections (aggressive reconnect loop) but pairing still doesn't occur. The oauthAccount is stored in runtime memory only — never written to the credentials file.

2. Extension's ir() fails silently on startup (feature flag race)

The extension's bridge init function ir() calls isFeatureEnabledAsync("chrome_ext_bridge_enabled") during startup. On a fresh extension load, the feature cache in chrome.storage.local is empty and there's no token yet to fetch flags from the API. The feature check returns false, nr() returns undefined, and ir() bails silently — no error, no retry.

3. Bun crash on Windows native messaging (known)

claude.exe --chrome-native-host crashes immediately when stdin is a pipe (Chrome's native messaging protocol). Bun v1.3.9-canary.51 panics with internal assertion failure. This blocks the native messaging fallback path entirely.

Crash report: https://bun.report/1.3.9/e_2d5628dbEkgggC+s1oU+vvkOu8t/uBysi5uB__qt24tCA0eNrzzCtJLcpLzFFILC5OLSrJzM9TSEvMzCktSgUAiSkKPg

4. No fallback from bridge to named pipes

lxE() always returns a bridge URL, making bridgeConfig always truthy in the factory function GaI(). The named pipe path (getSocketPaths / oOI()) never executes. When the bridge fails, there's no fallback.

Suggested Fixes

  1. Populate accountUuid eagerly — call Zn$() on startup, not only during token refresh
  2. Add retry logic to ir() — retry after feature cache loads and token becomes available
  3. Fix Bun stdin crash on Windows — or use Node.js for the native host
  4. Add bridge-to-pipe fallback — if bridge pairing fails after N seconds, fall back to named pipes
  5. Write oauthAccount to credentials file — so it survives process restarts without requiring token refresh

Related Issues

  • #23104 (Chrome extension not connecting)
  • #23218 (Windows native host issues)
  • #21300 (Chrome integration)
  • #24006 (Bridge connection issues)
  • #24199 (Pipe path mismatch — fixed in v2.1.39 but irrelevant due to bridge)

Reproduction

  1. Install Claude Code v2.1.39 on Windows 11
  2. Install Claude in Chrome extension v1.0.49
  3. Run claude --chrome
  4. Extension shows as installed/enabled in chrome://extensions
  5. Any Chrome MCP tool returns "Browser extension is not connected"

Diagnostic Data

Debug extension with 18 [BRIDGE-DBG] log markers available at ~/.claude/chrome/extension-debug/ — documents the full ir() flow and confirms all prerequisites pass except pairing.

View original on GitHub ↗

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