{"record":{"id":"20b117ae97eacc5d","repo":"n8n-io/n8n","slug":"page-not-found-pageid","errorCode":null,"errorMessage":"Page not found: ${pageId}","messagePattern":"Page not found: (.+?)","errorType":"exception","errorClass":"PageNotFoundError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/mcp-browser/src/adapters/agent-browser.ts","lineNumber":123,"sourceCode":"\t\t\tconst data = response.data as { tabs?: TabData[] } | undefined;\n\t\t\tthis.tabCache = data?.tabs ?? [];\n\t\t\tfor (const tab of this.tabCache) {\n\t\t\t\tthis.urlCache.set(tab.tabId, tab.url);\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tlog.debug('refreshTabs failed, assuming no active tabs available', { error: e });\n\t\t\tthis.tabCache = [];\n\t\t\tthis.urlCache.clear();\n\t\t}\n\t\treturn this.tabCache;\n\t}\n\n\tprivate async switchToTab(pageId: string): Promise<void> {\n\t\tlet tab = this.tabCache.find((t) => t.tabId === pageId);\n\t\tif (!tab) {\n\t\t\tawait this.refreshTabs();\n\t\t\ttab = this.tabCache.find((t) => t.tabId === pageId);\n\t\t\tif (!tab) throw new PageNotFoundError(pageId);\n\t\t}\n\t\tif (tab.active) return;\n\t\tawait this.run(['tab', tab.tabId]);\n\t\tfor (const t of this.tabCache) t.active = t.tabId === pageId;\n\t}\n\n\tprivate resolveTarget(target: ElementTarget): string {\n\t\tconst value =\n\t\t\t'ref' in target\n\t\t\t\t? target.ref.startsWith('@')\n\t\t\t\t\t? target.ref\n\t\t\t\t\t: `@${target.ref}`\n\t\t\t\t: target.selector;\n\t\treturn AgentBrowserAdapter.assertSafeArg(value, 'element target');\n\t}\n\n\tprivate static assertSafeArg(value: string, role: string): string {\n\t\tif (value.length > 1 && value.startsWith('-')) {","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/mcp-browser/src/adapters/agent-browser.ts#L105-L141","documentation":"Thrown as PageNotFoundError by switchToTab when the requested pageId is not found in the tab cache even after a refreshTabs() re-query. PageNotFoundError extends McpBrowserError and carries a hint: 'The page may have been closed. List open pages with browser_tab_list.' The message interpolates the pageId that was not resolved.","triggerScenarios":"Any adapter method that calls switchToTab(pageId) — click, type, snapshot, navigate, scroll, etc. — when pageId does not match any tab in the refreshed tab list. Happens when the tab was closed in the browser, the pageId is stale from a previous session, or the pageId is wrong/typo'd.","commonSituations":"The browser tab was closed by the user or by closePage since the last snapshot; the caller reused a pageId from before a reconnect (tabCache was rebuilt with new IDs); agent-browser returned a different tabId format after a version change; concurrent callers raced and one closed the tab.","solutions":["Call listTabs() to get the current valid page IDs and retry with a fresh one.","Take a new snapshot — the snapshot response carries current valid refs and tab IDs.","Avoid caching pageIds across reconnects; re-list after onDisconnect.","If using the agent-browser adapter, remember refreshTabs only retries once before throwing."],"exampleFix":"// before — reusing a stale pageId\nawait adapter.click(oldPageId, target);\n\n// after — re-list on failure\ntry {\n  await adapter.click(pageId, target);\n} catch (err) {\n  if (err instanceof PageNotFoundError) {\n    const tabs = await adapter.listTabs();\n    pageId = tabs[0].id;\n    await adapter.click(pageId, target);\n  } else throw err;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"import { PageNotFoundError } from '../errors';\n\nfunction isPageNotFound(error: unknown): boolean {\n  return error instanceof PageNotFoundError;\n}","tryCatchPattern":"try {\n  await adapter.click(pageId, target);\n} catch (err) {\n  if (err instanceof PageNotFoundError) {\n    const tabs = await adapter.listTabs();\n    pageId = tabs[0]?.id ?? pageId;\n    await adapter.click(pageId, target);\n  } else throw err;\n}","preventionTips":["Re-list tabs after any onDisconnect/reconnect — tab IDs change.","Do not cache pageIds across sessions.","Call listTabs() before the first interaction of a turn to refresh the cache."],"tags":["mcp-browser","tabs","agent-browser","stale-state"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}