{"record":{"id":"d99840c4b0d5fc39","repo":"jackwener/OpenCLI","slug":"bilibili-comments-reply-index-1-was-malformed","errorCode":null,"errorMessage":"Bilibili comments reply ${index + 1} was malformed","messagePattern":"Bilibili comments reply (.+?) was malformed","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/bilibili/comments.js","lineNumber":81,"sourceCode":"    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) {\n    if (!reply || typeof reply !== 'object' || Array.isArray(reply)) {\n        throw new CommandExecutionError(`Bilibili comments reply ${index + 1} was malformed`);\n    }\n    const rpid = String(reply.rpid ?? '').trim();\n    if (!rpid) {\n        throw new CommandExecutionError(`Bilibili comments reply ${index + 1} was missing rpid`);\n    }\n    const ctime = Number(reply.ctime);\n    if (!Number.isFinite(ctime)) {\n        throw new CommandExecutionError(`Bilibili comments reply ${index + 1} was missing ctime`);\n    }\n    return {\n        rank: index + 1,\n        rpid,\n        author: String(reply.member?.uname ?? ''),\n        text: String(reply.content?.message ?? '').replace(/\\n/g, ' ').trim(),\n        likes: reply.like ?? 0,\n        replies: reply.rcount ?? 0,\n        time: new Date(ctime * 1000).toISOString().slice(0, 16).replace('T', ' '),\n    };","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/bilibili/comments.js#L63-L99","documentation":"Thrown by formatReplyRow when an entry in the replies array is null, not an object, or an array — i.e. it cannot be formatted as a comment row. The CLI treats each reply as a structured object (rpid, ctime, member, content) and rejects anything else rather than emitting a broken row.","triggerScenarios":"Calling 'bilibili comments <bvid>' (or with --parent/--top) where the API returns a replies/top_replies array containing null or non-object elements at position index+1.","commonSituations":"Bilibili occasionally returns null entries inside reply lists for deleted/filtered comments; scraped or proxied responses with sanitized/emptied items; upstream schema drift.","solutions":["Retry the command — null entries are often transient from comment moderation","Drop --limit or paginate differently to avoid the problematic page","Filter non-object replies before formatting (or update the library version)","Report the video/rpid upstream if the API consistently returns malformed entries"],"exampleFix":"// before\nreturn replies.slice(0, limit).map(formatReplyRow);\n// after\nreturn replies.slice(0, limit)\n    .filter((r) => r && typeof r === 'object' && !Array.isArray(r))\n    .map(formatReplyRow);","handlingStrategy":"type-guard","validationCode":"const badIndex = replies.findIndex((r) => !r || typeof r !== 'object' || Array.isArray(r));\nif (badIndex !== -1) console.warn(`reply at index ${badIndex} is not an object`);","typeGuard":"function isReplyObject(reply) {\n    return !!reply && typeof reply === 'object' && !Array.isArray(reply);\n}","tryCatchPattern":"try {\n    const rows = await bilibiliComments(bvid);\n} catch (err) {\n    if (/reply \\d+ was malformed/.test(err.message)) {\n        // retry or treat as partial data\n    } else throw err;\n}","preventionTips":["Expect null entries in Bilibili reply lists","Filter malformed entries before formatting","Retry once before failing — entries are often transient","Report persistently malformed videos upstream"],"tags":["bilibili","data-shape","validation"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}