{"record":{"id":"5ab8c5b11871930c","repo":"jackwener/OpenCLI","slug":"invalid-illustration-id-illustid","errorCode":null,"errorMessage":"Invalid illustration ID: ${illustId}","messagePattern":"Invalid illustration ID: (.+?)","errorType":"validation","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/pixiv/download.js","lineNumber":30,"sourceCode":"import { CommandExecutionError, EmptyResultError, getErrorMessage } from '@jackwener/opencli/errors';\nimport { pixivFetch } from './utils.js';\ncli({\n    site: 'pixiv',\n    name: 'download',\n    access: 'read',\n    description: 'Download illustration images from Pixiv',\n    domain: 'www.pixiv.net',\n    strategy: Strategy.COOKIE,\n    args: [\n        { name: 'illust-id', positional: true, required: true, help: 'Illustration ID' },\n        { name: 'output', default: './pixiv-downloads', help: 'Output directory' },\n    ],\n    columns: ['index', 'type', 'status', 'size'],\n    func: async (page, kwargs) => {\n        const illustId = String(kwargs['illust-id'] ?? '');\n        const output = String(kwargs.output ?? './pixiv-downloads');\n        if (!/^\\d+$/.test(illustId)) {\n            throw new CommandExecutionError(`Invalid illustration ID: ${illustId}`);\n        }\n        // pixivFetch handles navigate + error checking; returns the response body directly\n        const pages = await pixivFetch(page, `/ajax/illust/${illustId}/pages`, {\n            notFoundMsg: `Illustration not found: ${illustId}`,\n        });\n        if (!Array.isArray(pages)) {\n            throw new CommandExecutionError('Pixiv pages API returned malformed payload');\n        }\n        if (pages.length === 0) {\n            throw new EmptyResultError('pixiv download', `No images found for illustration ${illustId}.`);\n        }\n        // Extract cookies for authenticated downloads\n        const cookies = formatCookieHeader(await page.getCookies({ domain: 'pixiv.net' }));\n        // Create output directory\n        const outputDir = path.join(output, illustId);\n        fs.mkdirSync(outputDir, { recursive: true });\n        const results = [];\n        for (let i = 0; i < pages.length; i++) {","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/pixiv/download.js#L12-L48","documentation":"Thrown by the pixiv download command when the --illust-id argument is not a plain positive integer string. The library validates the ID with /^\\d+$/ before making any network call, so malformed IDs fail fast instead of producing a bad pixiv AJAX request.","triggerScenarios":"Passing --illust-id with non-numeric characters (e.g. a full pixiv URL like 'https://www.pixiv.net/artworks/12345'), an empty string, a negative number, or an ID with leading/trailing whitespace.","commonSituations":"Users paste an entire artwork URL instead of just the numeric ID; shell quoting strips or adds characters; scripts pass an empty variable because an upstream lookup failed.","solutions":["Extract only the numeric portion of the ID, e.g. strip a URL down to the digits before passing --illust-id","Echo or print the value you are passing to confirm it is a non-empty digit-only string","Quote the argument in your shell so spaces/whitespace are not introduced","Check the upstream script/variable that produces the ID for an earlier failure returning empty output"],"exampleFix":"// before\npixiv download --illust-id https://www.pixiv.net/artworks/99876543\n// after\npixiv download --illust-id 99876543","handlingStrategy":"validation","validationCode":"const raw = String(kwargs['illust-id'] ?? '');\nconst m = raw.match(/(\\d+)\\s*$/);\nif (!m) throw new Error(`--illust-id must be numeric, got: ${raw}`);\nconst illustId = m[1];","typeGuard":"const isPixivId = (v) => typeof v === 'string' && /^\\d+$/.test(v.trim());","tryCatchPattern":"try {\n  await pixivDownload({ illustId });\n} catch (e) {\n  if (String(e.message).startsWith('Invalid illustration ID')) {\n    console.error(`Fix --illust-id (digits only): ${e.message}`);\n  } else throw e;\n}","preventionTips":["Strip URLs down to the numeric artwork ID before invoking the command","Validate IDs with /^\\d+$/ at the boundary of your own scripts","Quote CLI arguments to avoid stray whitespace","Fail fast on empty variables from upstream lookups"],"tags":["validation","cli","input"],"backgroundTag":"invalid-id-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}