jackwener/OpenCLI · error · ArgumentError

xianyu messages accepts either item_id/user_id or --rank, no

Error message

xianyu messages accepts either item_id/user_id or --rank, not both

What it means

The `xianyu messages` command supports two mutually exclusive targeting modes: an explicit item_id+user_id pair, or a `--rank` index pointing at a conversation from a prior `xianyu inbox` listing. Passing both at once is ambiguous, so ArgumentError is thrown from clis/xianyu/messages.js:37. It is an input-validation error, not a runtime/API failure.

Source

Thrown at clis/xianyu/messages.js:37

    access: 'read',
    description: '读取指定闲鱼私信会话的最近聊天内容',
    domain: 'www.goofish.com',
    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');

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pick one targeting mode: either pass --rank N (from xianyu inbox output) OR pass both --item_id and --user_id, never both styles.
  2. Remove the --rank flag if you intend to address the conversation by IDs.
  3. Remove --item_id/--user_id if you intend to pick the Nth inbox conversation by rank.
  4. In wrapper scripts, conditionally build the argument list based on which mode was selected.

Example fix

// before
await cli.run(['xianyu', 'messages', '--rank', '2', '--item_id', itemId, '--user_id', userId]);

// after
const args = byRank
  ? ['xianyu', 'messages', '--rank', String(rank)]
  : ['xianyu', 'messages', '--item_id', itemId, '--user_id', userId];
await cli.run(args);
Defensive patterns

Strategy: validation

Validate before calling

const modes = [rank > 0, Boolean(itemId || userId)].filter(Boolean).length;
if (modes > 1) throw new Error('use --rank OR item_id+user_id, not both');

Try / catch

try {
  await cli.run(args);
} catch (e) {
  if (e instanceof ArgumentError && /not both/.test(e.message)) {
    console.error('Fix invocation: drop --rank or drop --item_id/--user_id');
  } else throw e;
}

Prevention

When it happens

Trigger: Invoking the messages command with --rank greater than 0 while also supplying item_id and/or user_id, e.g. `xianyu messages --rank 2 --item_id 123 --user_id 456` or `--rank 1 --item_id 123`.

Common situations: Scripting a flow that iterates inbox results by rank but forgot to remove leftover item_id/user_id flags from a previous invocation; copy-pasting example commands and merging both argument styles; templated commands where optional kwargs are filled in unconditionally.

Related errors


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