{"record":{"id":"3986be4607b48fa7","repo":"jackwener/OpenCLI","slug":"title-must-be-at-most-max-title-len-characters","errorCode":null,"errorMessage":"Title must be at most ${MAX_TITLE_LEN} characters (got ${title.length})","messagePattern":"Title must be at most (.+?) characters \\(got (.+?)\\)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/notebooklm/create.js","lineNumber":16,"sourceCode":"import { cli, Strategy } from '@jackwener/opencli/registry';\nimport { ArgumentError, CommandExecutionError } from '@jackwener/opencli/errors';\nimport { NOTEBOOKLM_DOMAIN, NOTEBOOKLM_SITE } from './shared.js';\nimport { callNotebooklmRpc } from './rpc.js';\nimport { buildNotebooklmNotebookUrl, ensureNotebooklmHome, requireNotebooklmExecute, requireNotebooklmSession, verifyNotebooklmNotebookExists } from './utils.js';\n\nconst NOTEBOOKLM_CREATE_PROJECT_RPC_ID = 'CCqFvf';\nconst DEFAULT_EMOJI = '📒';\nconst MAX_TITLE_LEN = 200;\nconst NOTEBOOK_UUID_RE = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i;\n\nexport function parseCreateTitle(value) {\n    const title = String(value ?? '').trim();\n    if (!title) throw new ArgumentError('<title> is required');\n    if (title.length > MAX_TITLE_LEN) {\n        throw new ArgumentError(`Title must be at most ${MAX_TITLE_LEN} characters (got ${title.length})`);\n    }\n    return title;\n}\n\nexport function parseCreateEmoji(value) {\n    const emoji = String(value ?? '').trim();\n    if (!emoji) return DEFAULT_EMOJI;\n    return emoji;\n}\n\nexport function parseCreateProjectResult(result) {\n    let current = result;\n    while (Array.isArray(current) && current.length === 1 && Array.isArray(current[0])) {\n        current = current[0];\n    }\n    const id = Array.isArray(current)\n        ? (typeof current[2] === 'string' && current[2])\n            || (typeof current[0] === 'string' && current[0])","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/notebooklm/create.js#L1-L34","documentation":"parseCreateTitle enforces a maximum notebook title length of 200 characters (MAX_TITLE_LEN). Titles longer than that are rejected with this ArgumentError, reporting both the limit and the actual length, to match NotebookLM backend constraints before an RPC round-trip.","triggerScenarios":"Calling create with a title whose trimmed string length exceeds 200, e.g. pasting an entire document as the title.","commonSituations":"Programmatic use where a variable holding a long description is passed as title; multi-line pastes; generating titles from long prompts.","solutions":["Shorten the title to at most 200 characters before calling create.","Truncate programmatically: title.slice(0, 200) (after trim).","Move long content into sources (--content/--file) and keep the title a short label."],"exampleFix":"// before\nconst title = longDescription; // 350 chars\ncreate(title)\n// after\nconst title = longDescription.trim().slice(0, 200);\ncreate(title)","handlingStrategy":"validation","validationCode":"const title = String(rawTitle ?? '').trim();\nif (title.length > 200) throw new Error(`Title too long (${title.length}/200); truncate before calling create`);","typeGuard":null,"tryCatchPattern":"try {\n  await create(rawTitle);\n} catch (e) {\n  const m = String(e.message).match(/at most 200 characters \\(got (\\d+)\\)/);\n  if (m) return create(rawTitle.trim().slice(0, 200));\n  throw e;\n}","preventionTips":["Always slice(0, 200) programmatically derived titles.","Keep long text in sources, not the notebook title.","Unit-test title generation with worst-case long inputs."],"tags":["cli","argument-validation","length-limit","notebooklm"],"backgroundTag":"input-length-exceeded","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}