jackwener/OpenCLI · error · CommandExecutionError
NotebookLM RPC transport returned malformed response fields
Error message
NotebookLM RPC transport returned malformed response fields
What it means
fetchNotebooklmInPage evaluates an in-page fetch against NotebookLM's RPC endpoint and unwraps the evaluated result. Before returning it to callNotebooklmRpc, it validates the shape: ok must be boolean, status an integer, and body/requestUrl/finalUrl strings. If any field is missing or of the wrong type, the in-page bridge did not return a well-formed envelope, so this CommandExecutionError is thrown rather than propagating garbage downstream.
Source
Thrown at clis/notebooklm/rpc.js:214
body: request.method === 'GET' ? undefined : request.body,
credentials: 'include',
});
return {
ok: response.ok,
status: response.status,
body: await response.text(),
requestUrl,
finalUrl: response.url,
};
})()`);
}
catch (error) {
rethrowNotebooklmTransport(error, 'RPC transport');
}
const raw = requireNotebooklmObject(unwrapNotebooklmEvaluateResult(evaluated), 'RPC transport');
if (typeof raw.ok !== 'boolean' || !Number.isInteger(raw.status) || typeof raw.body !== 'string' || typeof raw.requestUrl !== 'string' || typeof raw.finalUrl !== 'string') {
throw new CommandExecutionError('NotebookLM RPC transport returned malformed response fields');
}
return {
ok: raw.ok,
status: raw.status,
body: raw.body,
requestUrl: raw.requestUrl,
finalUrl: raw.finalUrl,
};
}
export async function callNotebooklmRpc(page, rpcId, params, options = {}) {
const auth = await getNotebooklmPageAuth(page);
const requestBody = buildNotebooklmRpcBody(rpcId, params, auth.csrfToken);
const authuser = auth.authuser || '';
const url = NOTEBOOKLM_RPC_PATH +
`?rpcids=${rpcId}&source-path=${encodeURIComponent(auth.sourcePath)}` +
(authuser ? `&authuser=${encodeURIComponent(authuser)}` : '') +
`&hl=${encodeURIComponent(options.hl ?? 'en')}` +
`&f.sid=${encodeURIComponent(auth.sessionId)}&rt=c`;View on GitHub (pinned to 49907e53dc)
Solutions
- Re-run the command after confirming the NotebookLM tab is fully loaded on a notebook/home URL (not a login or error page).
- Re-open the session with `opencli notebooklm open <notebook>` so the adapter attaches to a fresh page before retrying.
- Check for recent NotebookLM UI changes; update opencli to the latest version that matches the current in-page response shape.
- If reproducible, log the raw evaluated value from unwrapNotebooklmEvaluateResult to identify which field is malformed and file an issue.
Example fix
// before: calling RPC on a page that may have navigated const res = await fetchNotebooklmInPage(page, method, body); // after: guard the session state first const state = await getNotebooklmPageState(page); if (state.kind === null) await openNotebooklmSession(page); const res = await fetchNotebooklmInPage(page, method, body);
Defensive patterns
Strategy: type-guard
Validate before calling
// before relying on the RPC envelope, verify the page is still on NotebookLM
const url = new URL(page.url());
if (!url.hostname.endsWith('notebooklm.google.com')) await reopenNotebooklmSession(page); Type guard
function isValidRpcEnvelope(raw) {
return !!raw && typeof raw === 'object' &&
typeof raw.ok === 'boolean' &&
Number.isInteger(raw.status) &&
typeof raw.body === 'string' &&
typeof raw.requestUrl === 'string' &&
typeof raw.finalUrl === 'string';
} Try / catch
try {
const res = await fetchNotebooklmInPage(page, method, body);
// use res
} catch (e) {
if (e instanceof CommandExecutionError && e.message.includes('malformed response fields')) {
await reopenNotebooklmSession(page); // recover by re-attaching a fresh page
} else throw e;
} Prevention
- Confirm the attached tab is fully loaded on a notebooklm.google.com URL before issuing RPC calls.
- Re-open the session after any navigation or long idle period.
- Pin a recent opencli version known to match the current NotebookLM frontend.
- Validate the envelope shape at call sites instead of assuming fetchNotebooklmInPage always succeeds.
When it happens
Trigger: The browser evaluate step in unwrapNotebooklmEvaluateResult returns null/undefined (page navigated mid-call, script injected into a non-NotebookLM frame), the in-page wrapper returns a partial object, or the serialized response loses fields (e.g. status became a string, body undefined).
Common situations: The tab navigated away or reloaded while the RPC fetch was in flight; the adapter page is actually a Chrome error page or login interstitial rather than the app; an NotebookLM frontend update changed the in-page hook the wrapper relies on; the CDP evaluate returned a serialized object with dropped fields.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- LinkedIn cookie lookup returned malformed payload
- NotebookLM file upload failed:
- NotebookLM AddFileSource (o4cbdc) RPC returned no source id;
- NotebookLM AddSources RPC returned no source id; verify the
- NotebookLM CreateProject RPC returned no notebook id
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/064bc9744e18c3e7.
Report an issue: GitHub.