{"record":{"id":"cf811d95c51535ad","repo":"jackwener/OpenCLI","slug":"bilibili-label-api-returned-malformed-replies","errorCode":null,"errorMessage":"Bilibili ${label} API returned malformed replies","messagePattern":"Bilibili (.+?) API returned malformed replies","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/bilibili/comments.js","lineNumber":61,"sourceCode":"            throw new AuthRequiredError('bilibili.com', `Bilibili ${label} API requires login or permission: ${message} (${payload.code})`);\n        }\n        throw new CommandExecutionError(`Bilibili ${label} API failed: ${message} (${payload.code})`);\n    }\n    return payload.data;\n}\n\nfunction requireReplies(data, label) {\n    if (!data || typeof data !== 'object' || Array.isArray(data)) {\n        throw new CommandExecutionError(`Bilibili ${label} API returned malformed data`);\n    }\n    if (!Object.hasOwn(data, 'replies')) {\n        throw new CommandExecutionError(`Bilibili ${label} API did not return replies`);\n    }\n    if (data.replies === null) {\n        return [];\n    }\n    if (!Array.isArray(data.replies)) {\n        throw new CommandExecutionError(`Bilibili ${label} API returned malformed replies`);\n    }\n    return data.replies;\n}\n\nfunction requireTopReplies(data, label) {\n    if (!data || typeof data !== 'object' || Array.isArray(data)) {\n        throw new CommandExecutionError(`Bilibili ${label} API returned malformed data`);\n    }\n    if (!Object.hasOwn(data, 'top_replies')) {\n        throw new CommandExecutionError(`Bilibili ${label} API did not return top_replies`);\n    }\n    if (!Array.isArray(data.top_replies)) {\n        throw new CommandExecutionError(`Bilibili ${label} API returned malformed top_replies`);\n    }\n    return data.top_replies;\n}\n\nfunction formatReplyRow(reply, index) {","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/bilibili/comments.js#L43-L79","documentation":"CommandExecutionError thrown by requireReplies when data.replies exists and is not null but is not an array. Bilibili's contract is replies: Reply[] | null; any other type is treated as a malformed response.","triggerScenarios":"API returns data.replies as an object, string, or number — typically due to a response-shape change or an intermediary rewriting the JSON.","commonSituations":"API version drift; corrupted/proxied responses; custom middleware or browser extensions modifying response bodies.","solutions":["Retry to rule out a transient corruption","Disable proxies/extensions that might rewrite the response","Update the library if Bilibili changed the field type"],"exampleFix":"null","handlingStrategy":"retry","validationCode":"null","typeGuard":"function isRepliesArray(d) { return !!d && (d.replies === null || Array.isArray(d.replies)); }","tryCatchPattern":"try { const rows = await run(['bilibili','comments',bvid]); } catch (e) { if (/malformed replies/.test(e.message)) return retryWithBackoff(fn, 2); throw e; }","preventionTips":["Validate replies is Array|null before consuming it downstream","Rule out proxies/extensions rewriting JSON bodies","Track Bilibili API version changes"],"tags":["api-response","schema-validation","upstream-error"],"backgroundTag":"api-malformed-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}