jackwener/OpenCLI · error · ArgumentError

url is required (positional)

Error message

url is required (positional)

What it means

requireXiaoePageUrl validates the positional url argument for xiaoe content commands. If the value is missing, empty, or not a non-empty string after trim, it throws ArgumentError('url is required (positional)').

Source

Thrown at clis/xiaoe/content.js:83

// Pure: count `<img>` elements whose src looks like a real xiaoe-hosted
// asset. `data:` URIs and non-xiaoe CDNs (avatars, ads) are excluded.
export function countXiaoeImages(doc) {
    let count = 0;
    const imgs = doc.querySelectorAll('img');
    for (let i = 0; i < imgs.length; i += 1) {
        const src = imgs[i].getAttribute('src') || imgs[i].src || '';
        if (!src) continue;
        if (src.startsWith('data:')) continue;
        if (!src.includes('xiaoe')) continue;
        count += 1;
    }
    return count;
}

export function requireXiaoePageUrl(value, commandName) {
    const raw = typeof value === 'string' ? value.trim() : '';
    if (!raw) {
        throw new ArgumentError('url is required (positional)');
    }
    let parsed;
    try {
        parsed = new URL(raw);
    } catch {
        throw new ArgumentError(
            `invalid xiaoe URL: ${raw}`,
            `Example: opencli xiaoe ${commandName} https://appxxxx.h5.xet.citv.cn/p/course/ecourse/v_xxxxx`,
        );
    }
    if (parsed.protocol !== 'https:') {
        throw new ArgumentError(
            `xiaoe URL must use https (got ${parsed.protocol.replace(':', '')})`,
            `Example: opencli xiaoe ${commandName} https://appxxxx.h5.xet.citv.cn/p/course/ecourse/v_xxxxx`,
        );
    }
    const host = parsed.hostname.toLowerCase();
    if (host !== 'h5.xet.citv.cn' && !host.endsWith('.h5.xet.citv.cn')) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass the xiaoe page URL as the positional argument: opencli xiaoe <command> https://appxxxx.h5.xet.citv.cn/p/course/...
  2. Quote the URL in the shell so special characters are not stripped.
  3. Run the command with --help to confirm the expected argument order.
  4. Check your wrapper script isn't dropping an empty/undefined variable into the URL slot.

Example fix

// before
opencli xiaoe content --format json
// after
opencli xiaoe content 'https://appxxxx.h5.xet.citv.cn/p/course/ecourse/v_xxxxx' --format json
Defensive patterns

Strategy: validation

Validate before calling

const url = process.argv[2];
if (!url || !url.trim()) {
  console.error('usage: opencli xiaoe <command> <url>');
  process.exit(2);
}

Type guard

const hasUrl = v => typeof v === 'string' && v.trim().length > 0;

Try / catch

try {
  await runCommand(args);
} catch (e) {
  if (e instanceof ArgumentError && /url is required/.test(e.message)) {
    console.error('Pass the xiaoe page URL as the first positional argument.');
    process.exit(2);
  } else throw e;
}

Prevention

When it happens

Trigger: Invoking a xiaoe content command (e.g. opencli xiaoe <subcommand>) without the positional URL, with an empty string, or passing the option in the wrong place so the parser yields undefined.

Common situations: Forgot the argument entirely; pasted only flags/options; shell quoting swallowed the URL; CLI argument-order change between versions leaving url undefined.

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/6631629cd810c476. Report an issue: GitHub.