Skip to content

[Bug]: /navigate route returns stale targetId after renderer-process swap (e.g. chrome-extension:// → https://) #25323

@stone-jin

Description

@stone-jin

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

  1. Chrome has only the Browser Relay extension settings page open (chrome-extension://…/options.html), no other tabs.
  2. Click the Relay toolbar icon to attach the settings page.
  3. Call POST /navigate with url = "https://www.xiaohongshu.com".
  4. Observe the response: targetId still refers to the old extension-page session, not the new page.
  5. Call POST /act or POST /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 targetId is 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 / 67bac62c2fix: Chrome relay extension auto-reattach after SPA navigation. This commit fixed the critical extension-side bug where Target.detachedFromTarget was not sent to the relay before re-attaching, causing stale entries to accumulate in connectedTargets. The server-side fix proposed here is a follow-up to ensure the /navigate response 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 in server-context.ts) correctly resolves subsequent operations to the new tab even when a stale targetId is passed — but agents inspecting the navigate response targetId still see stale data.
  • Workaround: Open a regular https:// page before attaching, so navigation stays within the same process model.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdedupe:parentPrimary canonical item in dedupe cluster

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions