{"record":{"id":"ecb6f08d2a3c4397","repo":"jackwener/OpenCLI","slug":"bilibili-conclusion-api-returned-malformed-outline-ecb6f0","errorCode":null,"errorMessage":"Bilibili conclusion API returned malformed outline point","messagePattern":"Bilibili conclusion API returned malformed outline point","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/bilibili/summary.js","lineNumber":118,"sourceCode":"\nfunction rowsFromModel(model) {\n    const rows = [{ time: '', content: model.summary }];\n    for (const section of model.outline) {\n        if (!section || typeof section !== 'object' || Array.isArray(section)) {\n            throw new CommandExecutionError('Bilibili conclusion API returned malformed outline section');\n        }\n        const sectionTitle = String(section.title ?? '').trim();\n        const sectionTime = formatTime(section.timestamp);\n        if (sectionTitle) {\n            rows.push({ time: sectionTime, content: `# ${sectionTitle}` });\n        }\n        const points = section.part_outline ?? [];\n        if (!Array.isArray(points)) {\n            throw new CommandExecutionError('Bilibili conclusion API returned malformed part outline');\n        }\n        for (const point of points) {\n            if (!point || typeof point !== 'object' || Array.isArray(point)) {\n                throw new CommandExecutionError('Bilibili conclusion API returned malformed outline point');\n            }\n            const content = String(point.content ?? '').trim();\n            if (content) {\n                rows.push({ time: formatTime(point.timestamp), content });\n            }\n        }\n    }\n    return rows;\n}\n\nvar command = cli({\n    site: 'bilibili',\n    name: 'summary',\n    access: 'read',\n    description: '获取 B站视频的官方 AI 总结（视频页「AI总结」同款，含分段大纲与时间戳）',\n    domain: 'www.bilibili.com',\n    strategy: Strategy.COOKIE,\n    args: [","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/bilibili/summary.js#L100-L136","documentation":"Within part_outline, each point must be a non-null, non-array object so its content/timestamp can be read safely. This CommandExecutionError fires when a point entry is null, a scalar, or an array, preventing crashes when building the time/content rows.","triggerScenarios":"A part_outline array contains null or non-object entries — placeholder/sentinel values from the API, truncated data, or incorrectly deserialized cached payloads.","commonSituations":"Videos with partially generated AI outlines; cache layers losing element types; unit-test fixtures with sloppy data.","solutions":["Log JSON.stringify of the failing points array to find the bad entry.","Skip invalid points with a filter: points.filter(p => p && typeof p === 'object' && !Array.isArray(p)).","Retry the conclusion request to rule out a transient bad payload.","Validate point shape when caching, not just when rendering.","Check for recent changes in the conclusion API's part_outline entries."],"exampleFix":"// before\nfor (const point of points) {\n    if (!point || typeof point !== 'object' || Array.isArray(point)) {\n        throw new CommandExecutionError('Bilibili conclusion API returned malformed outline point');\n    }\n// after\nfor (const point of points) {\n    if (!point || typeof point !== 'object' || Array.isArray(point)) {\n        console.warn('skipping malformed outline point', point);\n        continue;\n    }","handlingStrategy":"validation","validationCode":"const validPoints = (section?.part_outline ?? []).filter(\n  p => p && typeof p === 'object' && !Array.isArray(p)\n);\nif (validPoints.length !== (section?.part_outline ?? []).length) console.warn('some outline points invalid');","typeGuard":"function isOutlinePoint(p) {\n  return !!p && typeof p === 'object' && !Array.isArray(p) && ('content' in p || 'timestamp' in p);\n}","tryCatchPattern":"try {\n  const rows = rowsFromModel(model);\n} catch (e) {\n  if (String(e.message).includes('malformed outline point')) {\n    return [{ time: '', content: model.summary }];\n  }\n  throw e;\n}","preventionTips":["Filter points to non-null objects before iterating","Log the raw points array when a bad entry appears","Validate point shape before caching/serializing","Retry the request once to rule out transient bad data"],"tags":["bilibili","schema-validation","outline","data-mapping"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}