jackwener/OpenCLI · error · ArgumentError

url must be on h5.xet.citv.cn or a shop subdomain (got ${par

Error message

url must be on h5.xet.citv.cn or a shop subdomain (got ${parsed.hostname})

What it means

This ArgumentError is thrown by requireXiaoePageUrl when a xiaoe URL is passed whose hostname is not h5.xet.citv.cn and not a shop subdomain of it (e.g. appxxxx.h5.xet.citv.cn). The library only knows how to render and extract content from pages hosted on the xiaoe (小鹅通) H5 domain, so it rejects any other host up front before launching a browser. It is a pre-flight input validation guard.

Source

Thrown at clis/xiaoe/content.js:102

    }
    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')) {
        throw new ArgumentError(
            `url must be on h5.xet.citv.cn or a shop subdomain (got ${parsed.hostname})`,
            `Example: opencli xiaoe ${commandName} https://appxxxx.h5.xet.citv.cn/p/course/ecourse/v_xxxxx`,
        );
    }
    return parsed.toString();
}

export function buildContentScript() {
    return `
(() => {
  ${pickContentText.toString()}
  ${countXiaoeImages.toString()}
  const selectors = ${JSON.stringify(CONTENT_SELECTORS)};
  const title = document.title || '';
  const content = pickContentText(document, selectors, ${JSON.stringify(CONTENT_MIN_LENGTH)});
  const imageCount = countXiaoeImages(document);
  return [{
    title,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use a URL on h5.xet.citv.cn or a subdomain, e.g. https://appxxxx.h5.xet.citv.cn/p/course/ecourse/v_xxxxx
  2. Check parsed.hostname for typos (extra dashes, wrong TLD) and correct it
  3. If the shop uses a custom domain, ask the library maintainers or host the page under the *.h5.xet.citv.cn domain instead
  4. For course listing, use the xiaoe/courses command which targets study.xiaoe-tech.com instead

Example fix

// before
opencli xiaoe content https://app1234.xiaoe-tech.com/p/course/ecourse/v_abc
// after
opencli xiaoe content https://app1234.h5.xet.citv.cn/p/course/ecourse/v_abc
Defensive patterns

Strategy: validation

Validate before calling

function isXiaoePageUrl(url) {
  try {
    const h = new URL(url).hostname.toLowerCase();
    return h === 'h5.xet.citv.cn' || h.endsWith('.h5.xet.citv.cn');
  } catch { return false; }
}
if (!isXiaoePageUrl(input)) throw new Error('not a xiaoe h5 URL: ' + input);

Type guard

function isXiaoePageUrl(v) {
  try {
    const { hostname } = new URL(String(v));
    return hostname.toLowerCase() === 'h5.xet.citv.cn' || hostname.toLowerCase().endsWith('.h5.xet.citv.cn');
  } catch { return false; }
}

Try / catch

try {
  await runXiaoeCommand(url);
} catch (e) {
  if (e.name === 'ArgumentError' && /must be on h5\.xet\.citv\.cn/.test(e.message)) {
    console.error('Use a URL like https://appxxxx.h5.xet.citv.cn/... — got: ' + url);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `opencli xiaoe <command> <url>` with a URL pointing at a different host, e.g. xiaoe-tech.com, study.xiaoe-tech.com, a typo'd domain (h5.xit.citv.cn), http-vs-https confusion resolved to another host, or a re-hosted/proxied share link.

Common situations: Pasting a course link copied from WeChat that redirects through a different domain; using the management-console domain (study.xiaoe-tech.com) instead of the reader H5 domain; a shop migrating to a custom domain.

Related errors


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