diegosouzapw/OmniRoute · error · Error

Claude Web browser context no longer matches scoped UI…

Error message

Claude Web browser context no longer matches scoped UI template

What it means

Post-acquisition mismatch guard in sendClaudeWebBrowser: a retry template was found for the pool key, but after acquiring the browser context/page the prepared state (conversation or page state) no longer matches the scoped UI template captured earlier — e.g. the page navigated away, the conversation changed, or the pooled context was reused across a different session.

Solutions

  1. Discard the pooled context and fall back to a fresh completion turn
  2. Invalidate the stored browser template so subsequent retries re-capture it
  3. Verify cookieString/account scope used for the retry matches the one that captured the template
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at open-sse/executors/claude-web/browserTransport.ts:468 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of diegosouzapw/OmniRoute@a179ffed5b (2026-08-25). Data as JSON: /api/errors/238bb8443e5f454f. Report an issue: GitHub.

Appendix: source

Thrown at open-sse/executors/claude-web/browserTransport.ts:468

  const poolKey = buildClaudeWebBrowserPoolKey(request);
  const retryEntry =
    request.endpointSuffix === "retry_completion" ? lookupBrowserTemplate(poolKey) : null;
  if (request.endpointSuffix === "retry_completion" && !retryEntry) {
    throw new Error("Claude Web browser retry requires a scoped UI template");
  }

  const pooled = await deps.acquireContext(poolKey, {
    cookieDomain: ".claude.ai",
    cookieString: request.cookieString,
    warmupUrl: request.pageUrl,
    locale: request.locale,
    timezone: request.timezone,
    proxyProviderKey: "claude-web",
  });
  const page = await deps.openPage(pooled);
  try {
    if (retryEntry && retryEntry.context !== pooled.context) {
      throw new Error("Claude Web browser context no longer matches scoped UI template");
    }
    await page.goto(request.pageUrl, {
      waitUntil: "domcontentloaded",
      timeout: 60000,
    });
    throwIfAborted(request.signal);
    const fetchInput = retryEntry
      ? captureRetry(request, retryEntry.template)
      : await captureCompletion(page, request, poolKey, pooled.context);
    const captured = await withAbort(deps.fetchResponse(page, fetchInput), request.signal);
    if (captured.body.byteLength > MAX_CLAUDE_WEB_BROWSER_RESPONSE_BYTES) {
      throw new Error("Claude Web browser response exceeded the size limit");
    }
    return toTransportResult(captured);
  } finally {
    await page.close().catch(() => {});
  }
}

View on GitHub (pinned to a179ffed5b)