{"record":{"id":"d1d8c8070d32e8b5","repo":"jackwener/OpenCLI","slug":"failed-to-open-notebooklm-notebook-notebookid","errorCode":null,"errorMessage":"Failed to open NotebookLM notebook ${notebookId}: ${error?.message || error}","messagePattern":"Failed to open NotebookLM notebook (.+?): (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/notebooklm/generate-audio.js","lineNumber":68,"sourceCode":"    description: 'Trigger an Audio Overview (Deep Dive podcast) generation for a NotebookLM notebook, using all of its sources',\n    domain: NOTEBOOKLM_DOMAIN,\n    strategy: Strategy.COOKIE,\n    browser: true,\n    navigateBefore: false,\n    args: [\n        { name: 'notebook', positional: true, required: true, help: 'Notebook id from `notebooklm list` or full notebook URL' },\n        { name: 'execute', type: 'boolean', help: 'Actually trigger remote NotebookLM audio generation' },\n    ],\n    columns: ['notebook_id', 'audio_id', 'source_count', 'status', 'notebook_url'],\n    func: async (page, kwargs) => {\n        const notebookId = parseNotebooklmNotebookTarget(String(kwargs.notebook ?? ''));\n        requireNotebooklmExecute(kwargs.execute, 'generate NotebookLM audio');\n        try {\n            await page.goto(buildNotebooklmNotebookUrl(notebookId));\n            await page.wait(2);\n        }\n        catch (error) {\n            throw new CommandExecutionError(`Failed to open NotebookLM notebook ${notebookId}: ${error?.message || error}`);\n        }\n        await requireNotebooklmSession(page);\n        const sources = await listNotebooklmSourcesViaRpc(page);\n        const sourceIds = sources.map((s) => s.id).filter((id) => typeof id === 'string' && id);\n        if (sourceIds.length === 0) {\n            throw new EmptyResultError('notebooklm generate-audio', 'The notebook has no sources; add a source before generating an audio overview.');\n        }\n        const rpc = await callNotebooklmRpc(page, NOTEBOOKLM_CREATE_AUDIO_RPC_ID, buildCreateAudioArgs(notebookId, sourceIds));\n        const audioId = parseAudioIdFromResult(rpc.result, [notebookId, ...sourceIds]);\n        if (!audioId) {\n            throw new CommandExecutionError('NotebookLM CreateAudioOverview RPC returned no audio id; server may have rejected the request.');\n        }\n        return [{\n            notebook_id: notebookId,\n            audio_id: audioId,\n            source_count: sourceIds.length,\n            status: 'pending',\n            notebook_url: buildNotebooklmNotebookUrl(notebookId),","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/notebooklm/generate-audio.js#L50-L86","documentation":"This CommandExecutionError wraps any failure while navigating the adapter page to the target notebook's URL (`page.goto` + wait) during `notebooklm generate-audio`. It exists to attach the notebookId to the underlying navigation error.","triggerScenarios":"`page.goto(buildNotebooklmNotebookUrl(notebookId))` or `page.wait(2)` throws — invalid/malformed notebookId producing a bad URL, network timeout, session browser closed, or NotebookLM redirect to login.","commonSituations":"Typo'd or truncated notebook id; NotebookLM auth cookie expired so navigation redirects and errors; offline or rate-limited session; browser tab crashed.","solutions":["Check the notebookId is a valid NotebookLM notebook id/URL and correct typos.","Re-authenticate the NotebookLM session (refresh cookies / re-login) and retry.","Verify network connectivity and that the adapter browser session is alive, then rerun generate-audio."],"exampleFix":"// before\ncallGenerateAudio({ notebookId: 'abc' }) // typo id -> goto fails\n// after\nconst id = 'a1b2c3...verified-from-notebooklm-current'\ncallGenerateAudio({ notebookId: id })","handlingStrategy":"try-catch","validationCode":"if (!notebookId || !/^[A-Za-z0-9_-]+$/.test(notebookId)) throw new Error(`invalid notebookId: ${notebookId}`);\nconst state = await getNotebooklmPageState(page);\nif (!state) throw new Error('adapter session is not alive');","typeGuard":"const isValidNotebookId = (id) => typeof id === 'string' && id.trim().length > 0;","tryCatchPattern":"try {\n  await generateAudio({ notebookId });\n} catch (e) {\n  if (String(e.message).startsWith('Failed to open NotebookLM notebook')) {\n    await refreshNotebooklmSession();\n    return await generateAudio({ notebookId });\n  }\n  throw e;\n}","preventionTips":["Verify the notebook id via `notebooklm current` or `list` before generating.","Keep the NotebookLM session authenticated (fresh cookies).","Confirm network/proxy availability before long automation runs."],"tags":["notebooklm","navigation","command-execution","network"],"backgroundTag":"page-navigation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}