jackwener/OpenCLI · error · CommandExecutionError

Invalid illustration ID: ${illustId}

Error message

Invalid illustration ID: ${illustId}

What it means

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.

Source

Thrown at clis/pixiv/download.js:30

import { CommandExecutionError, EmptyResultError, getErrorMessage } from '@jackwener/opencli/errors';
import { pixivFetch } from './utils.js';
cli({
    site: 'pixiv',
    name: 'download',
    access: 'read',
    description: 'Download illustration images from Pixiv',
    domain: 'www.pixiv.net',
    strategy: Strategy.COOKIE,
    args: [
        { name: 'illust-id', positional: true, required: true, help: 'Illustration ID' },
        { name: 'output', default: './pixiv-downloads', help: 'Output directory' },
    ],
    columns: ['index', 'type', 'status', 'size'],
    func: async (page, kwargs) => {
        const illustId = String(kwargs['illust-id'] ?? '');
        const output = String(kwargs.output ?? './pixiv-downloads');
        if (!/^\d+$/.test(illustId)) {
            throw new CommandExecutionError(`Invalid illustration ID: ${illustId}`);
        }
        // pixivFetch handles navigate + error checking; returns the response body directly
        const pages = await pixivFetch(page, `/ajax/illust/${illustId}/pages`, {
            notFoundMsg: `Illustration not found: ${illustId}`,
        });
        if (!Array.isArray(pages)) {
            throw new CommandExecutionError('Pixiv pages API returned malformed payload');
        }
        if (pages.length === 0) {
            throw new EmptyResultError('pixiv download', `No images found for illustration ${illustId}.`);
        }
        // Extract cookies for authenticated downloads
        const cookies = formatCookieHeader(await page.getCookies({ domain: 'pixiv.net' }));
        // Create output directory
        const outputDir = path.join(output, illustId);
        fs.mkdirSync(outputDir, { recursive: true });
        const results = [];
        for (let i = 0; i < pages.length; i++) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Extract only the numeric portion of the ID, e.g. strip a URL down to the digits before passing --illust-id
  2. Echo or print the value you are passing to confirm it is a non-empty digit-only string
  3. Quote the argument in your shell so spaces/whitespace are not introduced
  4. Check the upstream script/variable that produces the ID for an earlier failure returning empty output

Example fix

// before
pixiv download --illust-id https://www.pixiv.net/artworks/99876543
// after
pixiv download --illust-id 99876543
Defensive patterns

Strategy: validation

Validate before calling

const raw = String(kwargs['illust-id'] ?? '');
const m = raw.match(/(\d+)\s*$/);
if (!m) throw new Error(`--illust-id must be numeric, got: ${raw}`);
const illustId = m[1];

Type guard

const isPixivId = (v) => typeof v === 'string' && /^\d+$/.test(v.trim());

Try / catch

try {
  await pixivDownload({ illustId });
} catch (e) {
  if (String(e.message).startsWith('Invalid illustration ID')) {
    console.error(`Fix --illust-id (digits only): ${e.message}`);
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/5ab8c5b11871930c. Report an issue: GitHub.