jackwener/OpenCLI · error · CommandExecutionError

NotebookLM page-state probe returned malformed Browser Bridg

Error message

NotebookLM page-state probe returned malformed Browser Bridge data

What it means

getNotebooklmPageState injects a probe script via the Browser Bridge that must return a plain object with typed fields (url, title, hostname, kind, notebookId, loginRequired, notebookCount). If the returned raw value is not an object or any field has the wrong type, this CommandExecutionError is thrown. It guards against the injected script failing, being blocked, or returning null/garbage so downstream URL classification never operates on bad data.

Source

Thrown at clis/notebooklm/utils.js:671

    const textNodes = Array.from(document.querySelectorAll('a, button, [role="button"], h1, h2'))
      .map(node => (node.textContent || '').trim().toLowerCase())
      .filter(Boolean);
    const loginRequired = path === '/login' || path.startsWith('/login/') || textNodes.some(text =>
      text.includes('sign in') ||
      text.includes('log in') ||
      text.includes('登录') ||
      text.includes('登入')
    );

    const notebookCount = Array.from(document.querySelectorAll('a[href*="/notebook/"]'))
      .map(node => node instanceof HTMLAnchorElement ? node.href : '')
      .filter(Boolean)
      .reduce((count, href, index, list) => list.indexOf(href) === index ? count + 1 : count, 0);

    return { url, title, hostname, kind, notebookId, loginRequired, notebookCount, path };
  })()`, 'page-state probe');
    if (!isPlainObject(raw) || typeof raw.url !== 'string' || typeof raw.title !== 'string' || typeof raw.hostname !== 'string' || typeof raw.kind !== 'string' || typeof raw.notebookId !== 'string' || typeof raw.loginRequired !== 'boolean' || typeof raw.notebookCount !== 'number' || !Number.isFinite(raw.notebookCount)) {
        throw new CommandExecutionError('NotebookLM page-state probe returned malformed Browser Bridge data');
    }
    let parsed;
    try {
        parsed = new URL(raw.url);
    }
    catch {
        throw new CommandExecutionError('NotebookLM page-state probe returned an invalid URL');
    }
    if (parsed.hostname !== raw.hostname) {
        throw new CommandExecutionError('NotebookLM page-state probe returned inconsistent URL and hostname fields');
    }
    const trusted = parseTrustedNotebooklmUrl(parsed.href);
    const kind = trusted ? classifyNotebooklmPage(trusted.href) : 'unknown';
    const notebookId = kind === 'notebook' ? parseNotebooklmIdFromUrl(trusted.href) : '';
    const loginPath = Boolean(trusted && (trusted.pathname === '/login' || trusted.pathname.startsWith('/login/')));
    const state = {
        url: raw.url,
        title: normalizeNotebooklmTitle(raw?.title, 'NotebookLM'),

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Reload the NotebookLM page and retry the state probe
  2. Confirm the page is actually on notebooklm.google.com (check page.url()) before probing
  3. Re-launch or re-attach the browser/Bridge if the tab crashed
  4. Update the library if NotebookLM's page structure changed the probe inputs
  5. Add a wait for page readiness (network idle / selector) before probing

Example fix

// before
const state = await getNotebooklmPageState(page);
// after: pre-validate location and retry on malformed probe
if (!page.url().includes('notebooklm.google.com')) await openNotebooklmHome(page);
let state;
try { state = await getNotebooklmPageState(page); }
catch (e) {
  if (!/malformed Browser Bridge data/.test(e.message)) throw e;
  await page.reload();
  state = await getNotebooklmPageState(page);
}
Defensive patterns

Strategy: type-guard

Validate before calling

function isValidPageState(raw) {
  return raw !== null && typeof raw === 'object'
    && typeof raw.url === 'string'
    && typeof raw.title === 'string'
    && typeof raw.hostname === 'string'
    && typeof raw.kind === 'string'
    && typeof raw.notebookId === 'string'
    && typeof raw.loginRequired === 'boolean'
    && typeof raw.notebookCount === 'number'
    && Number.isFinite(raw.notebookCount);
}

Type guard

function isNotebooklmPageState(v) {
  return v !== null && typeof v === 'object' && typeof v.url === 'string'
    && typeof v.hostname === 'string' && typeof v.notebookCount === 'number'
    && Number.isFinite(v.notebookCount) && typeof v.loginRequired === 'boolean';
}

Try / catch

try {
  const state = await getNotebooklmPageState(page);
} catch (e) {
  if (!/malformed Browser Bridge data/.test(e.message)) throw e;
  await page.reload(); // recover from error page / interrupted navigation
  const state = await getNotebooklmPageState(page);
}

Prevention

When it happens

Trigger: Calling getNotebooklmPageState when the evaluated probe returns non-object data — the page is on a chrome error page or about:blank, content script evaluation is blocked (CSP/extension), the browser bridge returns undefined on failure, or NotebookLM's page structure changed so a probe variable is undefined.

Common situations: Browser on an error/crash page instead of NotebookLM; navigation interrupted mid-probe; Browser Bridge desync after tab crash; future NotebookLM redesign removing fields the probe reads; headless environment quirks.

Understand the failure class

Related errors


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