jackwener/OpenCLI · error · ArgumentError

Expected a trusted HTTPS bilibili.com video URL without cred

Error message

Expected a trusted HTTPS bilibili.com video URL without credentials or a custom port

What it means

parseBvidOrVideoUrl validates that the parsed URL uses https, its hostname is in VIDEO_HOSTS (bilibili.com, www.bilibili.com, m.bilibili.com), and contains no username, password, or port. Any violation throws this ArgumentError. The strictness prevents SSRF-style tricks and untrusted hosts from being treated as bilibili video URLs.

Source

Thrown at clis/bilibili/utils.js:27

/**
 * Parse one exact, case-sensitive BVID or a trusted bilibili.com video URL.
 * Unlike the legacy short-link resolver, this is synchronous and never treats
 * malformed input as a b23.tv network lookup.
 */
export function parseBvidOrVideoUrl(value) {
    const raw = String(value ?? '').trim();
    if (EXACT_BVID_RE.test(raw)) return raw;

    let parsed;
    try {
        parsed = new URL(raw);
    }
    catch {
        throw new ArgumentError('Expected an exact BVID or bilibili.com video URL, for example BV1xx411c7mD');
    }
    if (!VIDEO_HOSTS.has(parsed.hostname) || parsed.protocol !== 'https:' || parsed.username || parsed.password || parsed.port) {
        throw new ArgumentError('Expected a trusted HTTPS bilibili.com video URL without credentials or a custom port');
    }
    const match = parsed.pathname.match(/^\/video\/(BV[0-9A-Za-z]{10})\/?$/);
    if (!match) {
        throw new ArgumentError('Bilibili video URL did not contain an exact case-sensitive BVID');
    }
    return match[1];
}
/**
 * Resolve Bilibili short URL / short code to BV ID.
 * Supports: BV1MV9NBtENN, XYzsqGa, b23.tv/XYzsqGa, https://b23.tv/XYzsqGa
 */
export function resolveBvid(input) {
    const trimmed = String(input).trim();
    if (/^BV[A-Za-z0-9]+$/i.test(trimmed)) {
        return Promise.resolve(trimmed);
    }
    try {
        const parsed = new URL(trimmed);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use the canonical https://www.bilibili.com/video/<BVID>/ form
  2. Resolve b23.tv short links to the full URL first (or use resolveBvid)
  3. Strip any credentials or port from the URL
  4. Only pass URLs whose hostname is exactly bilibili.com, www.bilibili.com, or m.bilibili.com

Example fix

// before
parseBvidOrVideoUrl('http://bilibili.com:8080/video/BV1xx411c7mD/');
// after
parseBvidOrVideoUrl('https://www.bilibili.com/video/BV1xx411c7mD/');
Defensive patterns

Strategy: validation

Validate before calling

function isTrustedBilibiliVideoUrl(v) {
  try {
    const u = new URL(String(v));
    return u.protocol === 'https:'
      && ['bilibili.com','www.bilibili.com','m.bilibili.com'].includes(u.hostname)
      && !u.username && !u.password && !u.port;
  } catch { return false; }
}

Type guard

function isHttpsNoCredsUrl(v) {
  if (!(v instanceof URL)) return false;
  return v.protocol === 'https:' && !v.username && !v.password && !v.port;
}

Try / catch

try {
  const bvid = parseBvidOrVideoUrl(url);
} catch (err) {
  if (err instanceof ArgumentError && /trusted HTTPS/.test(err.message)) {
    console.error(`Untrusted URL form: ${url}. Use https://www.bilibili.com/video/<BVID>/`);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling bvid/parseBvidOrVideoUrl with http:// (not https) URLs, other domains (e.g. b23.tv, spoofed look-alike hosts like bilibili.com.evil.com), URLs with embedded credentials (https://user:pass@bilibili.com/...), or an explicit port (https://bilibili.com:8443/video/...).

Common situations: Copying an http link from an old bookmark; using a short-link domain b23.tv with this strict parser; test fixtures using localhost:port URLs; proxy URLs that inject credentials.

Related errors


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