{"record":{"id":"9af73cadbf97cd51","repo":"jackwener/OpenCLI","slug":"cannot-resolve-aid-for-bvid-bvid","errorCode":null,"errorMessage":"Cannot resolve aid for bvid: ${bvid}","messagePattern":"Cannot resolve aid for bvid: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/bilibili/comment.js","lineNumber":55,"sourceCode":"        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));\n                if (!Number.isInteger(mid) || mid <= 0) {\n                    throw new CommandExecutionError(`Bilibili user search returned malformed mid for @${name}`);\n                }\n                atNameToMid[name] = mid;\n            }\n            catch (error) {\n                if (!(error instanceof EmptyResultError)) {","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/bilibili/comment.js#L37-L73","documentation":"After resolving the BV id, the CLI calls /x/web-interface/view to map bvid → aid, which the reply API requires as `oid`. If the payload parses but lacks `aid`, the library throws CommandExecutionError since it cannot address the video.","triggerScenarios":"requireOkPayload succeeds on /x/web-interface/view but viewData.aid is missing/0 — e.g. unexpected API response shape, region-locked or deleted video, or Bilibili schema change.","commonSituations":"Video removed or made region-private so view payload lacks aid; Bilibili API field rename; response intercepted by anti-bot page returning valid JSON without aid.","solutions":["Verify the video is publicly accessible (open the bvid URL in a browser)","Re-run later — transient API inconsistencies often resolve","Check for Bilibili API schema changes and update the CLI","Inspect the raw view API response for the bvid to confirm the aid field"],"exampleFix":"// before\nconst oid = viewData?.aid;\n// after\nconst oid = viewData?.aid ?? viewData?.id; // handle schema variants\nif (!oid) console.error('view payload:', JSON.stringify(viewData).slice(0, 200));","handlingStrategy":"validation","validationCode":"const view = await fetch(`https://api.bilibili.com/x/web-interface/view?bvid=${bvid}`).then(r => r.json());\nif (!view?.data?.aid) throw new Error(`No aid available for ${bvid}; video may be gone or region-locked`);","typeGuard":"const hasAid = (d) => d != null && typeof d.aid === 'number' && d.aid > 0;","tryCatchPattern":"try { await commentCmd(); } catch (e) { if (String(e.message).includes('Cannot resolve aid')) { console.error('Verify the video is public and retry'); } else throw e; }","preventionTips":["Verify video accessibility before scripting comments","Watch for Bilibili API schema changes and pin/inspect payloads","Retry transient API inconsistencies","Fall back to checking the video page for removal/region lock"],"tags":["api","schema-change","response-parsing"],"backgroundTag":"api-response-missing-field","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}