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
- Use a URL on h5.xet.citv.cn or a subdomain, e.g. https://appxxxx.h5.xet.citv.cn/p/course/ecourse/v_xxxxx
- Check parsed.hostname for typos (extra dashes, wrong TLD) and correct it
- If the shop uses a custom domain, ask the library maintainers or host the page under the *.h5.xet.citv.cn domain instead
- 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
- Only paste links whose host ends in .h5.xet.citv.cn into xiaoe commands
- Normalize URLs by parsing with new URL() and checking hostname before calling
- Watch for WeChat-shared links that redirect to alternate domains
- Use https explicitly; the same validator also requires it
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
- Bilibili summary URL must use http or https
- Bilibili summary URL must contain a BV video id
- Bilibili summary URL must be a bilibili.com or b23.tv URL
- No catalog rows extracted — the URL may not be a course page
- Unknown 12306 station telecode "${trimmed}"
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/367ddd349a007635.
Report an issue: GitHub.