{"record":{"id":"86d8c298fd595df5","repo":"jackwener/OpenCLI","slug":"cannot-resolve-bilibili-bv-id-from-input-string","errorCode":null,"errorMessage":"Cannot resolve Bilibili BV ID from input: ${String(kwargs.bvid ?? '')}","messagePattern":"Cannot resolve Bilibili BV ID from input: (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/bilibili/comment.js","lineNumber":48,"sourceCode":"    ],\n    columns: ['rpid', 'bvid', 'oid', 'message', 'url'],\n    func: async (page, kwargs) => {\n        if (!page) {\n            throw new CommandExecutionError('Browser session required for bilibili comment');\n        }\n        const message = String(kwargs.message ?? '').trim();\n        if (!message)\n            throw new ArgumentError('bilibili comment message cannot be empty');\n        // Write guard: posting is public and irreversible-ish, so require an explicit opt-in.\n        if (!kwargs.execute)\n            throw new ArgumentError('Refusing to post: pass --execute to actually publish this comment');\n        const parent = kwargs.parent != null ? readPositiveInteger(kwargs.parent, 'parent') : null;\n        let bvid;\n        try {\n            bvid = await resolveBvid(kwargs.bvid);\n        }\n        catch (error) {\n            throw new ArgumentError(`Cannot resolve Bilibili BV ID from input: ${String(kwargs.bvid ?? '')}`, error instanceof Error ? error.message : String(error));\n        }\n        // Resolve bvid → aid (the reply API addresses videos by aid, as `oid`)\n        const view = await apiGet(page, '/x/web-interface/view', { params: { bvid } });\n        const viewData = requireOkPayload(view, 'view');\n        const oid = viewData?.aid;\n        if (!oid)\n            throw new CommandExecutionError(`Cannot resolve aid for bvid: ${bvid}`);\n        // Resolve @username mentions to uids. Bilibili only turns \"@name\" into a real\n        // mention — one that notifies the mentioned user — when the request carries\n        // at_name_to_mid; a plain-text \"@name\" is otherwise inert and notifies nobody.\n        /** @type {Record<string, number>} */\n        const atNameToMid = {};\n        for (const match of message.matchAll(/@([^\\s@]+)/g)) {\n            const name = match[1];\n            if (name in atNameToMid)\n                continue;\n            try {\n                const mid = Number(await resolveUid(page, name));","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/bilibili/comment.js#L30-L66","documentation":"resolveBvid converts user input (URL, full link, or bare ID) into a canonical BV ID. When conversion fails the library wraps the underlying error in an ArgumentError echoing the original input, so the user sees what could not be parsed.","triggerScenarios":"--bvid contains a malformed ID, an unsupported URL format (e.g. a short link the resolver doesn't handle), or the underlying fetch inside resolveBvid fails (network/HTTP error) and is caught and rethrown here.","commonSituations":"Passing a full video page URL with query params the resolver mishandles; typo in the BV id; passing an av-number where a BV is expected; network failure during resolution.","solutions":["Pass the bare BV id (e.g. --bvid BV1xx411c7mD) or a canonical watch URL","Read the wrapped error.message (second argument) to see the root cause","Check network access to bilibili.com if the cause was a fetch failure","Verify the video still exists (deleted videos fail resolution)"],"exampleFix":"// before\ncli bilibili comment --bvid \"https://www.bilibili.com/video/BV1xx?spm_id_from=...\" --message hi --execute\n// after\ncli bilibili comment --bvid BV1xx411c7mD --message hi --execute","handlingStrategy":"validation","validationCode":"const m = String(bvidInput).match(/BV[0-9A-Za-z]{10}/);\nif (!m) throw new Error(`Input does not contain a valid BV id: ${bvidInput}`);","typeGuard":"const isBvid = (v) => typeof v === 'string' && /^BV[0-9A-Za-z]{10}$/.test(v.trim());","tryCatchPattern":"try { await commentCmd(); } catch (e) { if (String(e.message).includes('Cannot resolve Bilibili BV ID')) { console.error('Use a bare BV id, e.g. --bvid BV1xx411c7mD'); } else throw e; }","preventionTips":["Pass canonical BV ids rather than decorated URLs","Check the video still exists before commenting","Read the wrapped cause in the second error argument","Handle av-id vs bvid distinctions"],"tags":["argument-validation","parsing","input-validation"],"backgroundTag":"id-resolution-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}