{"record":{"id":"5b4245dbd4f8723b","repo":"jackwener/OpenCLI","slug":"file-path-is-not-a-regular-file-filepath","errorCode":null,"errorMessage":"--file path is not a regular file: ${filePath}","messagePattern":"--file path is not a regular file: (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/notebooklm/add-source.js","lineNumber":48,"sourceCode":"    '.wav': 'audio/wav',\n};\n\nexport function inferMimeType(filename, override) {\n    if (override) return String(override);\n    const ext = path.extname(filename).toLowerCase();\n    return MIME_BY_EXT[ext] || 'application/octet-stream';\n}\n\nexport function readFileForUpload(filePath) {\n    const abs = path.resolve(filePath);\n    let stat;\n    try {\n        stat = fs.statSync(abs);\n    } catch {\n        throw new ArgumentError(`--file path does not exist: ${filePath}`);\n    }\n    if (!stat.isFile()) {\n        throw new ArgumentError(`--file path is not a regular file: ${filePath}`);\n    }\n    if (stat.size > MAX_FILE_SOURCE_BYTES) {\n        throw new ArgumentError(`--file exceeds ${MAX_FILE_SOURCE_BYTES} bytes (got ${stat.size}); use a smaller file or upload via the NotebookLM UI for now.`);\n    }\n    const buf = fs.readFileSync(abs);\n    return { base64: buf.toString('base64'), filename: path.basename(abs), size: stat.size };\n}\n\nexport function buildRegisterFileSourceArgs(projectId, filename) {\n    return [\n        [[filename]],\n        projectId,\n        [2],\n        [1, null, null, null, null, null, null, null, null, null, [1]],\n    ];\n}\n\nexport function parseSourceUrl(value) {","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/notebooklm/add-source.js#L30-L66","documentation":"readFileForUpload throws this ArgumentError when the --file path stats successfully but stat.isFile() is false, i.e. the path is a directory, FIFO, socket, device, or other non-regular file. NotebookLM sources must be regular file uploads, so the library rejects anything else before reading it.","triggerScenarios":"Passing --file a directory path (most common), or a special file like /dev/stdin, a named pipe, or a Unix socket; also paths ending without a filename in glob-expanded shells.","commonSituations":"Forgetting to include the filename and passing just the folder; shell glob expansion producing a directory; trying to stream from /dev/stdin or a pipe instead of a real file.","solutions":["Point --file at a regular file, not a directory: include the full filename.","If you intended to upload a whole directory, iterate its files and add each one separately.","Materialize piped/stdin data into a temp file first, then pass that path.","Verify with `file <path>` or fs.statSync(p).isFile() before invoking."],"exampleFix":"// before\naddSource({ file: './notes' }); // directory\n// after\naddSource({ file: './notes/report.pdf' });","handlingStrategy":"validation","validationCode":"const stat = fs.statSync(filePath);\nif (!stat.isFile()) throw new Error(`Expected a regular file, got directory/special file: ${filePath}`);","typeGuard":"function isRegularFile(p) { try { return fs.statSync(path.resolve(p)).isFile(); } catch { return false; } }","tryCatchPattern":"try {\n  await addSource({ file: filePath });\n} catch (e) {\n  if (e instanceof ArgumentError && e.message.includes('not a regular file')) {\n    const stat = fs.statSync(filePath);\n    if (stat.isDirectory()) throw new Error('Pass a file inside ' + filePath + ', not the directory itself');\n  } else throw e;\n}","preventionTips":["Include the full filename — never point --file at a directory.","Verify with fs.statSync(p).isFile() before calling.","Avoid special files like /dev/stdin; materialize pipes into temp files.","Expand globs yourself and filter to regular files."],"tags":["filesystem","argument-validation","notebooklm","file-upload"],"backgroundTag":"path-is-not-a-file","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}