{"record":{"id":"b92e73725b61c7dd","repo":"jackwener/OpenCLI","slug":"notebooklm-addfilesource-o4cbdc-rpc-returned-no","errorCode":null,"errorMessage":"NotebookLM AddFileSource (o4cbdc) RPC returned no source id; cannot start file upload.","messagePattern":"NotebookLM AddFileSource \\(o4cbdc\\) RPC returned no source id; cannot start file upload\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/notebooklm/add-source.js","lineNumber":228,"sourceCode":"        const filePath = typeof kwargs.file === 'string' && kwargs.file.trim() ? kwargs.file.trim() : '';\n        const modes = [url ? 'url' : '', content !== null ? 'text' : '', filePath ? 'file' : ''].filter(Boolean);\n        if (modes.length === 0) {\n            throw new ArgumentError('Pass exactly one of --url <url>, --content <text>, or --file <path>');\n        }\n        if (modes.length > 1) {\n            throw new ArgumentError('Pass exactly one of --url, --content, --file (got: ' + modes.join(' + ') + ')');\n        }\n        requireNotebooklmExecute(kwargs.execute, 'add a NotebookLM source');\n        const title = parseSourceTitle(kwargs.title, 'Text Source');\n        await ensureNotebooklmHome(page);\n        await requireNotebooklmSession(page);\n        if (filePath) {\n            const file = readFileForUpload(filePath);\n            const mime = inferMimeType(file.filename, kwargs['mime-type']);\n            const registerRpc = await callNotebooklmRpc(page, NOTEBOOKLM_ADD_FILE_SOURCE_RPC_ID, buildRegisterFileSourceArgs(notebookId, file.filename));\n            const sourceId = parseAddSourceResult(registerRpc.result, [notebookId]);\n            if (!sourceId) {\n                throw new CommandExecutionError('NotebookLM AddFileSource (o4cbdc) RPC returned no source id; cannot start file upload.');\n            }\n            await uploadFileViaDriveResumable(page, notebookId, sourceId, file.filename, file.base64, file.size);\n            await verifyNotebooklmSourceAdded(page, notebookId, sourceId, 'add-source --file');\n            return [{\n                notebook_id: notebookId,\n                source_id: sourceId,\n                kind: 'file',\n                identifier: `${file.filename} (${mime}, ${file.size} bytes)`,\n                notebook_url: buildNotebooklmNotebookUrl(notebookId),\n            }];\n        }\n        const args = url\n            ? buildAddSourceFromUrlArgs(notebookId, url)\n            : buildAddSourceFromTextArgs(notebookId, title, content);\n        const rpc = await callNotebooklmRpc(page, NOTEBOOKLM_ADD_SOURCES_RPC_ID, args);\n        const sourceId = parseAddSourceResult(rpc.result, [notebookId]);\n        if (!sourceId) {\n            throw new CommandExecutionError('NotebookLM AddSources RPC returned no source id; verify the input reaches the NotebookLM backend.');","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/notebooklm/add-source.js#L210-L246","documentation":"After registering a file source via the NotebookLM AddFileSource RPC (id o4cbdc), the library parses the response for a source id. If none is found it cannot proceed to the Drive resumable upload, so it throws this CommandExecutionError. It indicates the backend rejected or failed the registration step.","triggerScenarios":"Calling `add-source --file <path>` where callNotebooklmRpc succeeds at the transport level but the o4cbdc response body contains no source id adjacent to the notebook id.","commonSituations":"Uploading an unsupported or zero-byte file type; the NotebookLM session is stale so the RPC silently fails; NotebookLM changed the RPC response schema; network interruption mid-RPC.","solutions":["Re-run the command after confirming an active NotebookLM session (browser login / auth refresh).","Verify the file type is supported by NotebookLM (pdf, txt, md, docx, audio, etc.) and that the file is non-empty.","Check whether the NotebookLM web UI can add the same file manually; if not, it is a backend/permission issue.","Capture the raw RPC result (logging) and compare against the expected schema — the RPC id may have changed."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (!fs.existsSync(filePath) || fs.statSync(filePath).size === 0) throw new Error(`File missing or empty: ${filePath}`);","typeGuard":null,"tryCatchPattern":"try {\n  await addSource({ file: path });\n} catch (e) {\n  if (String(e.message).includes('returned no source id')) {\n    // refresh session, verify file type supported, then retry once\n  }\n  throw e;\n}","preventionTips":["Verify the session is logged in before uploads.","Use supported, non-empty NotebookLM file types.","Manually test the same file in the NotebookLM web UI first."],"tags":["rpc","notebooklm","file-upload"],"backgroundTag":"rpc-response-missing-field","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}