#19766: fix: Chrome relay extension auto-reattach after SPA navigation
size: S
Cluster:
Chrome Extension Enhancements
## Summary
Fixes #19744 — The Chrome Browser Relay extension loses its CDP connection after any click that triggers SPA in-page navigation (Gmail, Google Calendar, etc.), making it effectively read-only for SPAs.
## Root Cause
`onDebuggerDetach` in `background.js` unconditionally calls `detachTab()` on any debugger detach event — including navigations where the tab still exists. It never attempts to re-attach, so the connection is permanently lost until the user manually clicks the extension badge again.
## Changes
**Core fix — `onDebuggerDetach` rewritten:**
- Detects navigation vs tab close (checks if tab still exists via `chrome.tabs.get`)
- Skips re-attach for `chrome://` and extension pages
- Sends `Target.detachedFromTarget` for old session before re-attaching (clean session handoff)
- **3 retries with exponential backoff** (300ms → 700ms → 1500ms) to handle varying page load times
- Each retry verifies: tab exists, relay connected, re-attach not cancelled by user
- Logs at each step for debugging (`chrome://extensions` service worker console)
**Race condition fixes:**
- `reattachPending` Set prevents concurrent re-attach loops for the same tab
- `connectOrToggleForActiveTab`: if user clicks badge during re-attach, cancels cleanly
- `onRelayClosed`: clears `reattachPending` so in-flight retries bail out immediately
**New: `chrome.tabs.onRemoved` listener:**
- Original code had no handler for tab removal — could leave stale state
- Now cleans up both `reattachPending` and `tabs` map on tab close
## Testing
Tested with:
- Gmail (clicking emails in inbox triggers SPA navigation)
- Google Calendar (navigating between days/weeks)
- Tabs that are closed during re-attach retry window
- User toggling badge during re-attach
## Files Changed
- `assets/chrome-extension/background.js` — 143 insertions, 2 deletions
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR fixes the Chrome Browser Relay extension losing its CDP connection after SPA in-page navigations (Gmail, Google Calendar, etc.) by rewriting `onDebuggerDetach` to detect whether the tab still exists and attempt automatic re-attachment with exponential backoff retries.
The approach is sound: it distinguishes navigation from tab close, cleans up old session state, notifies the relay, and retries with proper guards against races (concurrent re-attach, user toggle, relay disconnect, tab removal).
- **Key issue found:** The `reason` parameter from `chrome.debugger.onDetach` is not checked for `canceled_by_user` or `replaced_with_devtools`, which means the extension will fight the user's explicit action to dismiss the debugger bar by re-attaching 3 times before giving up.
- Race condition handling between `onRemoved` and `onDebuggerDetach` is correctly implemented.
- The new `chrome.tabs.onRemoved` listener properly cleans up stale state.
<h3>Confidence Score: 3/5</h3>
- Generally safe to merge but has a notable UX bug where the extension will fight user-initiated debugger dismissal
- The core SPA navigation re-attach logic is well-structured with proper race condition handling, but the missing check for `canceled_by_user` and `replaced_with_devtools` detach reasons is a real UX issue that will frustrate users who manually dismiss the debugger bar.
- `assets/chrome-extension/background.js` — the `onDebuggerDetach` function needs to check the `reason` parameter before attempting re-attach
<sub>Last reviewed commit: 0643000</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#16743: fix: auto-reattach browser relay debugger after navigation
by jg-noncelogic · 2026-02-15
91.4%
#17588: fix(relay): survive WS disconnects and MV3 worker restarts
by Unayung · 2026-02-15
84.6%
#15817: fix(chrome-relay): auto-reconnect, MV3 persistence, and keepalive
by derrickburns · 2026-02-13
84.4%
#10390: fix(chrome-relay): sticky attach + auto-restore after disconnects
by Mokoby · 2026-02-06
84.0%
#20688: fix(browser): allow extension reconnect when stale websocket linger...
by HOYALIM · 2026-02-19
79.4%
#22571: fix(browser): complete extension relay handshake on connect.challenge
by pandego · 2026-02-21
76.8%
#16689: browser: support multiple Chrome extension connections to relay
by globalcaos · 2026-02-15
76.3%
#16030: fix(browser): extend single-tab fallback to remote CDP profiles
by lailoo · 2026-02-14
76.3%
#13942: Fix: chrome-extension: make relay reconnect reliable with one tab
by gabepsilva · 2026-02-11
76.2%
#22385: fix: improve delivery recovery logging with entry age and deferral ...
by derrickburns · 2026-02-21
75.8%