jackwener/OpenCLI · error · CommandExecutionError
NotebookLM ${action} post-write verification failed: ${error
Error message
NotebookLM ${action} post-write verification failed: ${error?.message || error} What it means
Inside verifyNotebooklmNotebookExists, any error thrown while fetching or parsing the notebook detail that is not an AuthRequiredError or CommandExecutionError is wrapped into this CommandExecutionError with the original message appended. It means the post-write verification itself failed (network hiccup, malformed RPC payload, browser bridge failure), not necessarily that the notebook is missing.
Source
Thrown at clis/notebooklm/utils.js:483
const rpc = await callNotebooklmRpc(page, NOTEBOOKLM_NOTEBOOK_DETAIL_RPC_ID, [state.notebookId, null, [2], null, 0]);
return parseNotebooklmNotebookDetailResult(rpc.result);
}
export async function getNotebooklmNotebookDetailById(page, notebookId) {
const rpc = await callNotebooklmRpc(page, NOTEBOOKLM_NOTEBOOK_DETAIL_RPC_ID, [notebookId, null, [2], null, 0]);
return { detail: parseNotebooklmNotebookDetailResult(rpc.result), sources: parseNotebooklmSourceListResult(rpc.result) };
}
export async function verifyNotebooklmNotebookExists(page, notebookId, action) {
try {
const { detail } = await getNotebooklmNotebookDetailById(page, notebookId);
if (!detail || detail.id !== notebookId) {
throw new CommandExecutionError(`NotebookLM ${action} succeeded but the notebook ${notebookId} was not found in the post-write verification`);
}
return detail;
}
catch (error) {
if (error instanceof AuthRequiredError || error instanceof CommandExecutionError)
throw error;
throw new CommandExecutionError(`NotebookLM ${action} post-write verification failed: ${error?.message || error}`);
}
}
export async function verifyNotebooklmSourceAdded(page, notebookId, sourceId, action) {
try {
const { detail, sources } = await getNotebooklmNotebookDetailById(page, notebookId);
if (!detail || detail.id !== notebookId) {
throw new CommandExecutionError(`NotebookLM ${action} succeeded but the notebook ${notebookId} was not found in the post-write verification`);
}
const matched = sources.find((s) => s.id === sourceId);
if (!matched) {
throw new CommandExecutionError(`NotebookLM ${action} succeeded but source ${sourceId} did not appear in the notebook's source list`);
}
return matched;
}
catch (error) {
if (error instanceof AuthRequiredError || error instanceof CommandExecutionError)
throw error;
throw new CommandExecutionError(`NotebookLM ${action} post-write verification failed: ${error?.message || error}`);View on GitHub (pinned to 49907e53dc)
Solutions
- Inspect the inner error message appended after 'post-write verification failed:' to find the root cause
- Retry the verification — transient transport failures often succeed on a second attempt
- Reload the NotebookLM notebook page to re-establish page state before re-verifying
- Re-authenticate if the session expired (check for login redirects)
- Upgrade the library if NotebookLM changed its internal RPC schema
Example fix
// before: single-shot verify
await verifyNotebooklmNotebookExists(page, id, 'create');
// after: tolerate transient verification failures
try {
await verifyNotebooklmNotebookExists(page, id, 'create');
} catch (e) {
if (!/verification failed/.test(e.message)) throw e;
await page.wait(3);
await verifyNotebooklmNotebookExists(page, id, 'create');
} Defensive patterns
Strategy: retry
Validate before calling
// ensure page is on a NotebookLM notebook URL before verification
const url = page.url();
if (!/notebooklm\.google\.com\/.+/.test(url)) {
throw new Error('Page not on NotebookLM; verification would fail');
} Type guard
function isTransientVerificationError(e) {
return /post-write verification failed/.test(String(e?.message));
} Try / catch
try {
await verifyNotebooklmNotebookExists(page, id, action);
} catch (e) {
if (e instanceof AuthRequiredError || !isTransientVerificationError(e)) throw e;
await page.wait(2);
await verifyNotebooklmNotebookExists(page, id, action); // single retry
} Prevention
- Read the appended inner error message to identify root causes
- Retry transient transport failures before surfacing to users
- Reload the notebook page to re-establish Browser Bridge state
- Re-authenticate when inner messages indicate session loss
- Track NotebookLM RPC schema changes via library releases
When it happens
Trigger: getNotebooklmNotebookDetailById throws during verification — e.g. evaluateNotebooklm/RPC transport failure, parseNotebooklmNotebookDetailResult hitting a schema change (null detail path throws differently), timeouts waiting for the page, or a non-auth browser error while the verify wrapper converts it.
Common situations: Flaky network or page navigation during verification; Browser Bridge disconnect mid-RPC; NotebookLM RPC schema change returning unexpected payloads; slow page load making the detail probe fail before data arrives.
Related errors
- NotebookLM ${action} succeeded but the notebook ${notebookId
- NotebookLM ${action} succeeded but source ${sourceId} did no
- NOTEBOOKLM_TOKENS
- Not a git repository
- Working tree not clean: ${status}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/acac78c71b9efcfb.
Report an issue: GitHub.