{"record":{"id":"fc79821211fd6976","repo":"jackwener/OpenCLI","slug":"notebooklm-generate-audio","errorCode":null,"errorMessage":"notebooklm generate-audio","messagePattern":"notebooklm generate-audio","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"error","filePath":"clis/notebooklm/generate-audio.js","lineNumber":74,"sourceCode":"        { 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),\n        }];\n    },\n});\n\nexport const __test__ = { AUDIO_OVERVIEW_CONFIG_BLOCK, buildCreateAudioArgs, parseAudioIdFromResult };\n","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/notebooklm/generate-audio.js#L56-L92","documentation":"This EmptyResultError is thrown by `notebooklm generate-audio` when the notebook loaded successfully but `listNotebooklmSourcesViaRpc` returned zero usable source ids. Audio overviews require at least one source, so the library refuses to call the CreateAudioOverview RPC.","triggerScenarios":"Running generate-audio against an empty notebook (no sources added), or when the sources-list RPC fails to surface any string ids.","commonSituations":"User created a notebook and immediately tried audio generation without adding PDFs/links/notes; notebook freshly duplicated with sources still processing.","solutions":["Add at least one source to the notebook in NotebookLM (upload a file, paste a link, or add a note).","Re-run `opencli notebooklm generate-audio` after sources are present.","If sources exist but ids come back empty, retry later — sources may still be processing."],"exampleFix":"// before\nopencli notebooklm generate-audio --notebook <empty-notebook>\n// after\nopencli notebooklm add-source --notebook <id> --file report.pdf\nopencli notebooklm generate-audio --notebook <id>","handlingStrategy":"validation","validationCode":"const sources = await runCli(['notebooklm', 'sources', '--notebook', notebookId]);\nif (!sources.length) throw new Error('notebook has no sources; add one before generating audio');","typeGuard":"const hasSources = (sources) => Array.isArray(sources) && sources.some((s) => typeof s?.id === 'string' && s.id);","tryCatchPattern":"try {\n  await generateAudio({ notebookId });\n} catch (e) {\n  if (String(e.message).includes('notebooklm generate-audio') && String(e.message).includes('no sources')) {\n    throw new Error('Precondition failed: add sources to the notebook first');\n  }\n  throw e;\n}","preventionTips":["Check source count before invoking audio generation.","Wait for freshly added sources to finish processing.","Add sources programmatically (add-source) before audio steps in pipelines."],"tags":["notebooklm","empty-result","precondition","audio"],"backgroundTag":"notebook-has-no-sources","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}