jackwener/OpenCLI · error

Target tab ${candidate} is not part of the current browser s

Error message

Target tab ${candidate} is not part of the current browser session. The Browser Bridge session may have restarted; re-run "opencli browser tab list" and choose a current target.

What it means

The tab candidate was validated against the live session but is not among the current tabs — i.e. page.tabs() succeeded and the requested target ID/index is gone. The library treats this as a stale-target condition, throws this descriptive error, and (for saved targets) clears the stored target state first.

Source

Thrown at src/cli.ts:591

      return undefined;
    }
    throw new Error(
      `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.',
      { cause: err },
    );
  }

  if (Array.isArray(tabs) && hasBrowserTabTarget(tabs, candidate)) {
    return candidate;
  }

  if (opts.source === 'saved') {
    saveBrowserTargetState(undefined, opts.scope);
    return undefined;
  }

  throw new Error(
    `Target tab ${candidate} is not part of the current browser session. ` +
    'The Browser Bridge session may have restarted; re-run "opencli browser tab list" and choose a current target.',
  );
}

function getBrowserScope(session: string, contextId?: string): string {
  return contextId ? `${contextId}:${session}` : session;
}

async function resolveStoredBrowserTarget(page: import('./types.js').IPage, scope: string): Promise<string | undefined> {
  const defaultPage = loadBrowserTargetState(scope)?.defaultPage?.trim();
  if (!defaultPage) return undefined;
  return resolveBrowserTargetInSession(page, defaultPage, { scope, source: 'saved' });
}

/** Create a browser page for browser commands. Uses a named browser session for continuity. */
async function getBrowserPage(
  session: string,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Run `opencli browser tab list` and choose a currently listed target.
  2. Clear the saved browser target state so future runs re-resolve fresh (it is auto-cleared when source is 'saved').
  3. Make scripts resolve tabs by URL/pattern at run time instead of persisting IDs.
  4. Reopen the needed tab if it was closed.

Example fix

// before
await runBrowser(savedTargetId);
// after
const tabs = await page.tabs();
const target = tabs.find(t => t.url.startsWith('https://app.example.com'));
if (!target) throw new Error('target tab not found; re-list tabs');
Defensive patterns

Strategy: fallback

Validate before calling

async function targetExists(page, candidate) {
  const tabs = await page.tabs();
  return tabs.some(t => String(t.id) === String(candidate));
}

Type guard

function isCurrentTab(candidate: string, tabs: Tab[]): boolean {
  return tabs.some(t => String(t.id) === String(candidate));
}

Try / catch

try {
  await resolveBrowserTargetInSession(page, candidate, opts);
} catch (err) {
  if (err instanceof Error && err.message.includes('is not part of the current browser session')) {
    const tabs = await page.tabs();
    return resolveBrowserTargetInSession(page, tabs[0]?.id, opts);
  }
  throw err;
}

Prevention

When it happens

Trigger: resolveBrowserTargetInSession is called with a candidate not present in page.tabs(): referencing a tab that was closed, a saved target from a previous browser session, or an index/ID that shifted after tabs were opened or reordered.

Common situations: Scripts caching tab IDs across runs; a browser restart invalidating all saved targets; the tab closed by the page itself (window.close) or by another automation run.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/f505361e6af54e49. Report an issue: GitHub.