-
-
Notifications
You must be signed in to change notification settings - Fork 52.6k
Description
Summary
After browser navigate causes a Chrome renderer-process swap (e.g. navigating from chrome-extension:// to https://), the /navigate response still returns the pre-navigation targetId because tab.targetId is captured before navigateViaPlaywright and never refreshed.
Steps to reproduce
- Chrome has only the Browser Relay extension settings page open (
chrome-extension://…/options.html), no other tabs. - Click the Relay toolbar icon to attach the settings page.
- Call
POST /navigatewithurl = "https://www.xiaohongshu.com". - Observe the response:
targetIdstill refers to the old extension-page session, not the new page. - Call
POST /actorPOST /snapshot— on older extension versions without Chrome relay extension: CDP connection drops after SPA in-page navigation (click actions) #19744, operations execute on the extension page instead of the intended target.
Expected behavior
The navigate response returns the post-navigation targetId corresponding to the new page. Subsequent operations target the navigated page.
Actual behavior
The navigate response returns the pre-navigation targetId (from the extension settings page). The url field in the response shows the correct final URL, but targetId is stale. On extension versions prior to #19744 (67bac62c2), the stale session entry also persists in the relay's connectedTargets, causing subsequent act/evaluate operations to execute on the wrong page entirely.
OpenClaw version
2026.2.22-2
Operating system
macOS 26.2 (Darwin 25.2.0)
Install method
pnpm global
Logs, screenshots, and evidence
The `/navigate` route in `src/browser/routes/agent.snapshot.ts` captures `tab` before navigation and returns `tab.targetId` after:
run: async ({ cdpUrl, tab, pw }) => {
const result = await pw.navigateViaPlaywright({
cdpUrl,
targetId: tab.targetId, // captured before navigation
url,
...withBrowserNavigationPolicy(ctx.state().resolved.ssrfPolicy),
});
res.json({ ok: true, targetId: tab.targetId, ...result });
// ^^^^^^^^^^^^^^^^ stale after renderer swap
},
When Chrome's renderer process changes during navigation:
1. The old session/targetId is invalidated by the debugger detach.
2. The extension re-attaches with a new `sessionId` and `targetId` (after 300–1500ms).
3. The navigate route has already captured `tab.targetId` from before step 1.
4. The response carries the stale targetId.
**Fix:** After `navigateViaPlaywright`, re-resolve the current tab via `profileCtx.listTabs()` matching by URL. If the old target is gone but the new one isn't visible yet (extension re-attach in progress), retry after 800ms. See branch `fix/browser-relay-stale-session-after-navigation`.Impact and severity
- Affected: Extension relay mode users navigating across process boundaries (chrome-extension:// → https://, or cross-origin navigations triggering a process swap).
- Severity: Medium — the navigate response
targetIdis incorrect, which may confuse agents that rely on it. On extension versions without Chrome relay extension: CDP connection drops after SPA in-page navigation (click actions) #19744, severity is High (operations execute on wrong page). - Frequency: 100% reproducible when navigating from the extension settings page.
- Consequence: Agents receive a stale targetId from navigate; subsequent operations may target the wrong page or require
ensureTabAvailable's single-candidate fallback to recover.
Additional information
- Related: Chrome relay extension: CDP connection drops after SPA in-page navigation (click actions) #19744 /
67bac62c2— fix: Chrome relay extension auto-reattach after SPA navigation. This commit fixed the critical extension-side bug whereTarget.detachedFromTargetwas not sent to the relay before re-attaching, causing stale entries to accumulate inconnectedTargets. The server-side fix proposed here is a follow-up to ensure the/navigateresponse metadata is also correct. - With the extension fix from Chrome relay extension: CDP connection drops after SPA in-page navigation (click actions) #19744 in place,
ensureTabAvailable's single-candidate fallback (lines 417–425 inserver-context.ts) correctly resolves subsequent operations to the new tab even when a stale targetId is passed — but agents inspecting the navigate responsetargetIdstill see stale data. - Workaround: Open a regular
https://page before attaching, so navigation stays within the same process model.