jackwener/OpenCLI · error · ArgumentError
invalid xiaoe URL: ${raw}
Error message
invalid xiaoe URL: ${raw} What it means
requireXiaoePageUrl attempts new URL(raw) on the supplied value; when the string is not a parseable absolute URL it throws ArgumentError('invalid xiaoe URL: <raw>') with an example of the expected format.
Source
Thrown at clis/xiaoe/content.js:89
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')) {
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();View on GitHub (pinned to 49907e53dc)
Solutions
- Include the full scheme: https://appxxxx.h5.xet.citv.cn/p/course/ecourse/v_xxxxx.
- Quote the URL in the shell so ?, &, and # are not interpreted.
- Trim whitespace and remove any surrounding text before pasting.
- Validate in JS beforehand with new URL(value) inside try/catch.
Example fix
// before opencli xiaoe content appxxxx.h5.xet.citv.cn/p/course/ecourse/v_xxxxx // after opencli xiaoe content 'https://appxxxx.h5.xet.citv.cn/p/course/ecourse/v_xxxxx'
Defensive patterns
Strategy: validation
Validate before calling
function assertHttpsUrl(raw) {
let u;
try { u = new URL(String(raw).trim()); } catch { throw new Error(`invalid xiaoe URL: ${raw}`); }
if (u.protocol !== 'https:') throw new Error('must use https');
return u;
} Type guard
const isAbsoluteHttpUrl = v => { try { const u = new URL(v); return u.protocol === 'https:' || u.protocol === 'http:'; } catch { return false; } }; Try / catch
try {
await contentCommand(url);
} catch (e) {
if (e instanceof ArgumentError && /invalid xiaoe URL/.test(e.message)) {
console.error('Include the full https:// scheme and quote the URL.');
process.exit(2);
} else throw e;
} Prevention
- Always copy the complete URL including https://.
- Quote URLs containing ?, &, # in the shell.
- Pre-validate with new URL() in scripts that build the URL programmatically.
When it happens
Trigger: Passing a relative path ('/p/course/...'), a bare host ('appxxxx.h5.xet.citv.cn'), a malformed URL, or a value with stray whitespace/characters so the URL constructor throws.
Common situations: Copy-paste truncated the 'https://' prefix; shell mangled query strings (?, &) that weren't quoted; pasted a URL with surrounding text or trailing punctuation; passed an app-specific deep link that isn't an HTTP URL.
Related errors
- --url must be a Discord channel URL like https://discord.com
- --url must be a Discord thread/post URL like https://discord
- id not a valid Grok URL (got "${input}")
- Invalid Instagram URL: ${raw}
- job-id must be a Midjourney UUID or https://www.midjourney.c
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/7d531e1dfc7af753.
Report an issue: GitHub.