{"record":{"id":"2a62667765d30973","repo":"jackwener/OpenCLI","slug":"bilibili-video-url-did-not-contain-an-exact-case-s","errorCode":null,"errorMessage":"Bilibili video URL did not contain an exact case-sensitive BVID","messagePattern":"Bilibili video URL did not contain an exact case-sensitive BVID","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/bilibili/utils.js","lineNumber":31,"sourceCode":" * malformed input as a b23.tv network lookup.\n */\nexport function parseBvidOrVideoUrl(value) {\n    const raw = String(value ?? '').trim();\n    if (EXACT_BVID_RE.test(raw)) return raw;\n\n    let parsed;\n    try {\n        parsed = new URL(raw);\n    }\n    catch {\n        throw new ArgumentError('Expected an exact BVID or bilibili.com video URL, for example BV1xx411c7mD');\n    }\n    if (!VIDEO_HOSTS.has(parsed.hostname) || parsed.protocol !== 'https:' || parsed.username || parsed.password || parsed.port) {\n        throw new ArgumentError('Expected a trusted HTTPS bilibili.com video URL without credentials or a custom port');\n    }\n    const match = parsed.pathname.match(/^\\/video\\/(BV[0-9A-Za-z]{10})\\/?$/);\n    if (!match) {\n        throw new ArgumentError('Bilibili video URL did not contain an exact case-sensitive BVID');\n    }\n    return match[1];\n}\n/**\n * Resolve Bilibili short URL / short code to BV ID.\n * Supports: BV1MV9NBtENN, XYzsqGa, b23.tv/XYzsqGa, https://b23.tv/XYzsqGa\n */\nexport function resolveBvid(input) {\n    const trimmed = String(input).trim();\n    if (/^BV[A-Za-z0-9]+$/i.test(trimmed)) {\n        return Promise.resolve(trimmed);\n    }\n    try {\n        const parsed = new URL(trimmed);\n        if (/(\\.|^)bilibili\\.com$/i.test(parsed.hostname)) {\n            const match = parsed.pathname.match(/\\/(?:video|bangumi\\/play)\\/(BV[A-Za-z0-9]+)/i);\n            if (match) {\n                return Promise.resolve(match[1]);","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/bilibili/utils.js#L13-L49","documentation":"After host/scheme validation succeeds, parseBvidOrVideoUrl requires pathname to match /^\\/video\\/(BV[0-9A-Za-z]{10})\\/?$/ exactly, case-sensitively. If the path doesn't contain an exact BVID segment, this ArgumentError is thrown. Note the BVID returned by this function preserves the case of the input.","triggerScenarios":"URLs to other bilibili pages (space, bangumi/play, opus), /video/ URLs whose id is not a BV id (older av numbers), BVIDs with wrong length or lowercase 'bv' prefix, URLs with extra path segments or query strings in the pathname match failure (query is fine, but e.g. /video/BV1xx411c7mD/extra is not).","commonSituations":"Passing a bangumi/season link instead of a /video/ link; sharing mobile app links with extra tracking path segments; hand-transcribed BVIDs with a missing/extra character; passing av-number URLs (video/av170001).","solutions":["Use a /video/BV... URL whose BVID is exactly 12 chars: 'BV' + 10 alphanumerics","Convert av-numbers to BV ids (or use a resolver that accepts av numbers)","Remove trailing path segments after the BVID","Check character-by-character that the BVID matches what bilibili.com shows (case-sensitive)"],"exampleFix":"// before\nparseBvidOrVideoUrl('https://www.bilibili.com/bangumi/play/BV1xx411c7mD/');\n// after\nparseBvidOrVideoUrl('https://www.bilibili.com/video/BV1xx411c7mD/');","handlingStrategy":"validation","validationCode":"function extractBvidFromUrl(v) {\n  const m = String(v ?? '').match(/\\/video\\/(BV[0-9A-Za-z]{10})\\/?(?:[?#].*)?$/);\n  return m ? m[1] : null; // null => don't call parseBvidOrVideoUrl\n}","typeGuard":"function hasBvidPath(v) {\n  try { return /^\\/video\\/BV[0-9A-Za-z]{10}\\/?$/.test(new URL(String(v)).pathname); }\n  catch { return false; }\n}","tryCatchPattern":"try {\n  const bvid = parseBvidOrVideoUrl(url);\n} catch (err) {\n  if (err instanceof ArgumentError && /case-sensitive BVID/.test(err.message)) {\n    console.error(`URL is not a /video/BV... page: ${url}`);\n  } else throw err;\n}","preventionTips":["Ensure the link is a /video/ page, not bangumi/space/opus","Verify the BVID is 'BV' + exactly 10 alphanumerics, case preserved","Strip extra path segments after the BVID from shared links","Convert av-numbers to BV ids before passing them"],"tags":["argument-validation","bilibili","url-parsing"],"backgroundTag":"invalid-video-id-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}