{"record":{"id":"9c9094a66687a4af","repo":"jackwener/OpenCLI","slug":"unsupported-novel-download-format-format-supp","errorCode":null,"errorMessage":"Unsupported novel download format: ${format}. Supported formats: txt, md.","messagePattern":"Unsupported novel download format: (.+?)\\. Supported formats: txt, md\\.","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/pixiv/novel-download-utils.js","lineNumber":53,"sourceCode":"    ...body,\n    id: novelId,\n    title,\n    userName: author,\n    userId,\n    content: body.content,\n    createdDate,\n    wordCount,\n    bookmarkCount,\n  };\n}\n\nexport function normalizeNovelFileFormat(value) {\n  if (value !== undefined && typeof value !== 'string') {\n    throw new ArgumentError('Novel download format must be txt or md');\n  }\n  const format = (value ?? 'txt').toLowerCase();\n  if (format !== 'txt' && format !== 'md') {\n    throw new ArgumentError(`Unsupported novel download format: ${format}. Supported formats: txt, md.`);\n  }\n  return format;\n}\n\nexport function normalizePixivOutputRoot(value, fallback) {\n  if (value !== undefined && typeof value !== 'string') {\n    throw new ArgumentError('output must be a directory path');\n  }\n  const raw = value ?? fallback;\n  if (!raw || raw.includes('\\0')) {\n    throw new ArgumentError('output must be a non-empty directory path');\n  }\n  const resolved = path.resolve(raw);\n  let ancestor = resolved;\n  const missingParts = [];\n  let ancestorStat;\n  while (!ancestorStat) {\n    try {","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/pixiv/novel-download-utils.js#L35-L71","documentation":"After type-checking, normalizeNovelFileFormat lowercases the value (defaulting undefined to 'txt') and throws this ArgumentError if the result is neither 'txt' nor 'md'. This guards against unsupported output formats before any file is written.","triggerScenarios":"Passing --format pdf, docx, html, or any misspelling like 'markdown' or 'text' to the novel download command.","commonSituations":"Users assume other formats are supported; typo'd values like 'md.' or 'TXT ' with punctuation/whitespace (note: no trimming is done, so ' txt' fails); scripted values from an upstream config.","solutions":["Use exactly 'txt' or 'md' as the format value","Trim whitespace and remove punctuation from the value before passing it","Update the calling script/config to one of the supported formats","If another format is needed, extend normalizeNovelFileFormat's allowed set"],"exampleFix":"// before\npixiv novel-download --format markdown\n// after\npixiv novel-download --format md","handlingStrategy":"validation","validationCode":"const allowed = new Set(['txt', 'md']);\nconst fmt = String(options.format ?? 'txt').trim().toLowerCase();\nif (!allowed.has(fmt)) throw new Error(`Unsupported format: ${fmt}; use txt or md`);","typeGuard":"const isSupportedFormat = (v) => v === 'txt' || v === 'md';","tryCatchPattern":"try {\n  await novelDownload({ format });\n} catch (e) {\n  if (/Unsupported novel download format/.test(e.message)) {\n    console.error('Use --format txt or --format md');\n  } else throw e;\n}","preventionTips":["Use only 'txt' or 'md' for the format option","Trim and lowercase values before passing through wrappers","Do not assume other formats (pdf/html) are supported","List allowed formats in your own CLI help/config docs"],"tags":["validation","cli","argument"],"backgroundTag":"unsupported-format-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}