jackwener/OpenCLI · error · CommandExecutionError

Invalid user ID: ${userId}

Error message

Invalid user ID: ${userId}

What it means

Thrown by the pixiv illusts command when the --user-id argument is not a digit-only string. Like the illust ID check, it validates with /^\d+$/ before calling /ajax/user/{id}/profile/all.

Source

Thrown at clis/pixiv/illusts.js:27

import { CommandExecutionError } from '@jackwener/opencli/errors';
import { pixivFetch, BATCH_SIZE } from './utils.js';
cli({
    site: 'pixiv',
    name: 'illusts',
    access: 'read',
    description: "List a Pixiv artist's illustrations",
    domain: 'www.pixiv.net',
    strategy: Strategy.COOKIE,
    args: [
        { name: 'user-id', positional: true, required: true, help: 'Pixiv user ID' },
        { name: 'limit', type: 'int', default: 20, help: 'Number of results' },
    ],
    columns: ['rank', 'title', 'illust_id', 'pages', 'bookmarks', 'tags', 'created', 'url'],
    func: async (page, kwargs) => {
        const userId = String(kwargs['user-id'] ?? '');
        const limit = Number(kwargs.limit) || 20;
        if (!/^\d+$/.test(userId)) {
            throw new CommandExecutionError(`Invalid user ID: ${userId}`);
        }
        // Step 1: get all illust IDs
        const profileBody = await pixivFetch(page, `/ajax/user/${userId}/profile/all`, {
            notFoundMsg: `User not found: ${userId}`,
        });
        const allIds = Object.keys(profileBody?.illusts || {})
            .sort((a, b) => Number(b) - Number(a))
            .slice(0, limit);
        if (allIds.length === 0)
            return [];
        // Step 2: batch fetch details (Pixiv supports up to ~48 IDs per request)
        const allWorks = {};
        for (let offset = 0; offset < allIds.length; offset += BATCH_SIZE) {
            const batch = allIds.slice(offset, offset + BATCH_SIZE);
            const idsParam = batch.map(id => `ids[]=${id}`).join('&');
            // pixivFetch navigates on each call; for subsequent batches we re-navigate,
            // which is fine — the cookie is already attached.
            const detailBody = await pixivFetch(page, `/ajax/user/${userId}/profile/illusts?${idsParam}&work_category=illustManga&is_first_page=${offset === 0 ? 1 : 0}`);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use the numeric pixiv user ID (visible in the profile URL as /users/12345), not the account name
  2. Extract digits from a profile URL: https://www.pixiv.net/users/12345 -> 12345
  3. Print the value being passed to confirm it is non-empty and digit-only
  4. Fix the upstream data source that supplies the user ID

Example fix

// before
pixiv illusts --user-id someuser
// after
pixiv illusts --user-id 12345
Defensive patterns

Strategy: validation

Validate before calling

const raw = String(kwargs['user-id'] ?? '');
if (!/^\d+$/.test(raw)) throw new Error(`--user-id must be numeric, got: ${raw}`);

Type guard

const isPixivUserId = (v) => /^\d+$/.test(String(v).trim());

Try / catch

try {
  await pixivIllusts({ userId });
} catch (e) {
  if (String(e.message).startsWith('Invalid user ID')) {
    console.error('Use the numeric ID from /users/<id>, not the account name');
  } else throw e;
}

Prevention

When it happens

Trigger: Passing a pixiv username/screen name instead of the numeric user ID, an empty value, or an ID copied with extra text (e.g. from a profile URL query string).

Common situations: Confusing the pixiv display name or URL alias (e.g. 'someuser') with the internal numeric user ID; automation passing an unset variable.

Related errors


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