{"record":{"id":"46991149f9ab8a3e","repo":"jackwener/OpenCLI","slug":"target-tab-candidate-could-not-be-validated-in","errorCode":null,"errorMessage":"Target tab ${candidate} could not be validated in the current browser session. The Browser Bridge session may have restarted; re-run \"opencli browser tab list\" and choose a current target.","messagePattern":"Target tab (.+?) could not be validated in the current browser session\\. The Browser Bridge session may have restarted; re-run \"opencli browser tab list\" and choose a current target\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli.ts","lineNumber":575,"sourceCode":"}\n\nasync function resolveBrowserTargetInSession(\n  page: import('./types.js').IPage,\n  targetPage: string,\n  opts: { scope: string; source: 'explicit' | 'saved' },\n): Promise<string | undefined> {\n  const candidate = targetPage.trim();\n  if (!candidate) return undefined;\n\n  let tabs: unknown[];\n  try {\n    tabs = await page.tabs();\n  } catch (err) {\n    if (opts.source === 'saved') {\n      saveBrowserTargetState(undefined, opts.scope);\n      return undefined;\n    }\n    throw new Error(\n      `Target tab ${candidate} could not be validated in the current browser session. ` +\n      'The Browser Bridge session may have restarted; re-run \"opencli browser tab list\" and choose a current target.',\n      { cause: err },\n    );\n  }\n\n  if (Array.isArray(tabs) && hasBrowserTabTarget(tabs, candidate)) {\n    return candidate;\n  }\n\n  if (opts.source === 'saved') {\n    saveBrowserTargetState(undefined, opts.scope);\n    return undefined;\n  }\n\n  throw new Error(\n    `Target tab ${candidate} is not part of the current browser session. ` +\n    'The Browser Bridge session may have restarted; re-run \"opencli browser tab list\" and choose a current target.',","sourceCodeStart":557,"sourceCodeEnd":593,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/src/cli.ts#L557-L593","documentation":"When resolving an explicitly requested browser tab, the CLI calls page.tabs() to enumerate current targets. If that call itself throws (the bridge connection is dead, e.g. the browser session restarted), the code clears any saved target state is only cleared for saved-source lookups; for explicit candidates it throws an Error telling the user the candidate could not be validated and to re-list tabs, with the original error as cause.","triggerScenarios":"resolveBrowserTargetInSession('explicit') invoked and page.tabs() rejects — the Browser Bridge websocket died, the browser was closed/restarted, or the session name no longer maps to a live page between resolving and validating.","commonSituations":"Long-lived scripts holding a session while the browser auto-updates or crashes; referencing a saved tab ID in a new terminal after the bridge restarted; running two CLI sessions where one closes the shared browser.","solutions":["Re-run `opencli browser tab list` to see currently valid targets and pick one of those.","Reopen or reattach the browser session before retrying the command.","Handle the retry in scripts: catch, re-list, and re-resolve the target instead of caching tab IDs across runs.","Inspect the `cause` property of the error for the underlying transport failure if the bridge seems up."],"exampleFix":"// before\nconst tab = savedTabId; // stale across restarts\nawait run(tab);\n// after\nconst tabs = await listTabs();\nconst tab = tabs.find(t => t.url.includes('/reports'))?.id ?? tabs[0].id;\nawait run(tab);","handlingStrategy":"retry","validationCode":"async function bridgeIsAlive(page) {\n  try { await page.tabs(); return true; } catch { return false; }\n}\nif (!(await bridgeIsAlive(page))) throw new Error('Browser Bridge is down; restart the session');","typeGuard":"function isAliveTabsResult(v: unknown): v is Tab[] {\n  return Array.isArray(v) && v.every(t => typeof t === 'object' && t !== null && 'id' in t);\n}","tryCatchPattern":"try {\n  await resolveBrowserTargetInSession(page, candidate, { source: 'explicit' });\n} catch (err) {\n  if (err instanceof Error && err.message.includes('could not be validated')) {\n    await restartBrowserSession();\n    const tabs = await listTabs();\n    candidate = pickTarget(tabs);\n    return resolveBrowserTargetInSession(page, candidate, { source: 'explicit' });\n  }\n  throw err;\n}","preventionTips":["Don't cache tab IDs across script runs; re-resolve each run.","Run `opencli browser tab list` before long automations to verify the bridge.","Handle browser restarts/crashes in scripts with a re-list-and-retry step.","Keep only one automation session driving the shared browser."],"tags":["browser","session","stale-state","tab-targeting"],"backgroundTag":"stale-browser-target","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}