jackwener/OpenCLI · error · ArgumentError

xianyu messages requires both item_id and user_id, or --rank

Error message

xianyu messages requires both item_id and user_id, or --rank from xianyu inbox

What it means

`xianyu messages` requires a complete targeting spec when not using --rank: item_id and user_id must be supplied together. When exactly one of the two is present (hasItemId !== hasUserId) and rank is 0, ArgumentError is thrown at clis/xianyu/messages.js:40. The conversation is keyed by the (item_id, user_id) pair, so one half alone cannot identify a chat.

Source

Thrown at clis/xianyu/messages.js:40

    strategy: Strategy.COOKIE,
    navigateBefore: false,
    browser: true,
    args: [
        { name: 'item_id', positional: true, help: '闲鱼商品 item_id' },
        { name: 'user_id', positional: true, help: '聊一聊对方的 user_id / peerUserId' },
        { name: 'limit', type: 'int', default: DEFAULT_MESSAGE_LIMIT, help: 'Number of visible messages to return' },
        { name: 'rank', type: 'int', default: 0, help: 'Conversation rank from xianyu inbox; clicks the visible row instead of requiring IDs' },
    ],
    columns: ['index', 'peer_name', 'item_title', 'message', 'item_id', 'peer_user_id', 'url'],
    func: async (page, kwargs) => {
        const hasItemId = kwargs.item_id != null && kwargs.item_id !== '';
        const hasUserId = kwargs.user_id != null && kwargs.user_id !== '';
        const rank = normalizeRank(kwargs.rank);
        if (rank > 0 && (hasItemId || hasUserId)) {
            throw new ArgumentError('xianyu messages accepts either item_id/user_id or --rank, not both');
        }
        if (rank === 0 && hasItemId !== hasUserId) {
            throw new ArgumentError('xianyu messages requires both item_id and user_id, or --rank from xianyu inbox');
        }
        if (rank === 0 && !hasItemId && !hasUserId) {
            throw new ArgumentError('xianyu messages requires item_id/user_id or --rank from xianyu inbox');
        }
        const hasIds = hasItemId && hasUserId;
        const itemId = hasIds ? normalizeNumericId(kwargs.item_id, 'item_id', '1038951278192') : '';
        const userId = hasIds ? normalizeNumericId(kwargs.user_id, 'user_id', '3650092411') : '';
        const limit = normalizeLimit(kwargs.limit, DEFAULT_MESSAGE_LIMIT, MAX_MESSAGE_LIMIT, 'messages --limit');
        let url = '';
        if (hasIds) {
            url = buildChatUrl(itemId, userId);
            await page.goto(url);
        } else {
            if (!page.getCurrentUrl || !/https:\/\/www\.goofish\.com\/im\b/.test(await page.getCurrentUrl())) {
                await page.goto('https://www.goofish.com/im');
            }
        }
        await page.wait(2);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Supply both --item_id and --user_id together (IDs are available from xianyu inbox / xianyu messages output).
  2. Alternatively use --rank N to select the Nth conversation from the most recent xianyu inbox run.
  3. Check for empty strings: kwargs with value '' count as absent, so `--item_id 123 --user_id ""` triggers this — fix the caller's data.
  4. Validate the pair exists in your data source before invoking the command.

Example fix

// before
await cli.run(['xianyu', 'messages', '--item_id', conv.itemId]);

// after
if (!conv.userId) throw new Error('cannot fetch messages without user_id');
await cli.run(['xianyu', 'messages', '--item_id', conv.itemId, '--user_id', conv.userId]);
Defensive patterns

Strategy: validation

Validate before calling

if (!rank && (!itemId || !userId)) throw new Error('messages needs both item_id and user_id, or --rank');

Try / catch

try {
  await cli.run(['xianyu', 'messages', '--item_id', itemId, '--user_id', userId]);
} catch (e) {
  if (e instanceof ArgumentError && /requires both item_id and user_id/.test(e.message)) {
    const conv = await inboxLookup(itemId); // resolve missing user_id upstream
    return retryWithUserId(conv.peer_user_id);
  }
  throw e;
}

Prevention

When it happens

Trigger: Running `xianyu messages --item_id 123` without --user_id, or `xianyu messages --user_id 456` without --item_id, with no (or a zero) --rank value.

Common situations: Partial data from an upstream system — e.g. only the item id was recorded and the counterparty user id was lost; one flag accidentally commented out or failing an emptiness check in generated CLI calls; confusing item_id with user_id and passing the same value twice under one flag name.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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