{"record":{"id":"4d25cd9888e32183","repo":"jackwener/OpenCLI","slug":"notebooklm-label-returned-a-malformed-browser-b","errorCode":null,"errorMessage":"NotebookLM ${label} returned a malformed Browser Bridge payload","messagePattern":"NotebookLM (.+?) returned a malformed Browser Bridge payload","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/notebooklm/rpc.js","lineNumber":8,"sourceCode":"import { AuthRequiredError, CliError, CommandExecutionError } from '@jackwener/opencli/errors';\nimport { NOTEBOOKLM_DOMAIN, parseTrustedNotebooklmUrl } from './shared.js';\n\nconst NOTEBOOKLM_RPC_PATH = '/_/LabsTailwindUi/data/batchexecute';\n\nfunction requireNotebooklmObject(value, label) {\n    if (!value || typeof value !== 'object' || Array.isArray(value)) {\n        throw new CommandExecutionError(`NotebookLM ${label} returned a malformed Browser Bridge payload`);\n    }\n    return value;\n}\n\nfunction rethrowNotebooklmTransport(error, label) {\n    if (error instanceof CliError)\n        throw error;\n    throw new CommandExecutionError(`NotebookLM ${label} failed: ${error?.message || error}`);\n}\n\nexport function unwrapNotebooklmEvaluateResult(payload) {\n    if (payload && typeof payload === 'object' && !Array.isArray(payload) && 'session' in payload && 'data' in payload) {\n        return payload.data;\n    }\n    return payload;\n}\n\nexport function extractNotebooklmPageAuthFromHtml(html, sourcePath = '/', preferredTokens) {","sourceCodeStart":1,"sourceCodeEnd":26,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/notebooklm/rpc.js#L1-L26","documentation":"requireNotebooklmObject validates that a value evaluated inside the NotebookLM Chrome page via the Browser Bridge is a non-null, non-array plain object. When the in-page script returns nothing, a primitive, or an array instead of the expected object envelope, the helper throws this CommandExecutionError so downstream field access cannot proceed on garbage data. It is a shape contract at the transport boundary.","triggerScenarios":"requireNotebooklmObject(unwrapNotebooklmEvaluateResult(evaluated), 'page auth probe') returns null/undefined/an array/a string because the in-page evaluate failed to produce the expected {session,data} object, or unwrapNotebooklmEvaluateResult returned payload.data that is not an object.","commonSituations":"NotebookLM page not fully loaded so the injected script returns undefined; a NotebookLM frontend update changed the evaluate envelope shape; the page is on a redirect/login interstitial so the script short-circuits; stale Chrome session with a cached old script.","solutions":["Reload the NotebookLM notebook page in Chrome and wait for full load before retrying","Re-authenticate / open the notebook in an already logged-in session","Retry with --verbose to inspect the raw evaluate payload","Update the CLI, since a NotebookLM frontend change may have altered the payload envelope"],"exampleFix":"// before (fragile direct access)\nconst raw = await page.evaluate(() => collect());\nconsole.log(raw.html);\n// after (guard first)\nconst raw = await page.evaluate(() => collect());\nif (!raw || typeof raw !== 'object' || Array.isArray(raw)) throw new Error('unexpected payload');\nconsole.log(raw.html);","handlingStrategy":"type-guard","validationCode":"const raw = unwrapNotebooklmEvaluateResult(evaluated);\nif (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n  throw new Error('Browser Bridge returned no object payload; reload the NotebookLM page');\n}","typeGuard":"function isBridgeObject(v) {\n  return v !== null && typeof v === 'object' && !Array.isArray(v);\n}","tryCatchPattern":"try {\n  const raw = unwrapNotebooklmEvaluateResult(evaluated);\n  if (!isBridgeObject(raw)) throw new Error('malformed payload');\n  // use raw\n} catch (e) {\n  console.error('Browser Bridge payload invalid, reload the notebook page:', e.message);\n}","preventionTips":["Ensure the NotebookLM page is fully loaded before invoking commands","Keep the CLI updated so the in-page collector matches the current page script","Verify the Chrome tab is on a real notebook page, not a login interstitial"],"tags":["browser-bridge","payload-validation","notebooklm"],"backgroundTag":"browser-bridge-malformed-payload","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}