jackwener/OpenCLI · error · CommandExecutionError

Bilibili conclusion API returned malformed outline section

Error message

Bilibili conclusion API returned malformed outline section

What it means

rowsFromModel iterates model.outline and validates each section is a non-null, non-array object before reading its title/timestamp. A section failing this check triggers this CommandExecutionError, protecting downstream String(section.title) and property access from crashes on nulls or scalars.

Source

Thrown at clis/bilibili/summary.js:105

    if (!modelResult || typeof modelResult !== 'object' || Array.isArray(modelResult)) {
        throw new CommandExecutionError('Bilibili conclusion API returned malformed model_result');
    }
    const summary = String(modelResult.summary ?? '').trim();
    if (!summary) {
        throw new EmptyResultError('bilibili summary', `Bilibili has not generated an AI summary for ${bvid}.`);
    }
    const outline = modelResult.outline ?? [];
    if (!Array.isArray(outline)) {
        throw new CommandExecutionError('Bilibili conclusion API returned malformed outline');
    }
    return { summary, outline };
}

function rowsFromModel(model) {
    const rows = [{ time: '', content: model.summary }];
    for (const section of model.outline) {
        if (!section || typeof section !== 'object' || Array.isArray(section)) {
            throw new CommandExecutionError('Bilibili conclusion API returned malformed outline section');
        }
        const sectionTitle = String(section.title ?? '').trim();
        const sectionTime = formatTime(section.timestamp);
        if (sectionTitle) {
            rows.push({ time: sectionTime, content: `# ${sectionTitle}` });
        }
        const points = section.part_outline ?? [];
        if (!Array.isArray(points)) {
            throw new CommandExecutionError('Bilibili conclusion API returned malformed part outline');
        }
        for (const point of points) {
            if (!point || typeof point !== 'object' || Array.isArray(point)) {
                throw new CommandExecutionError('Bilibili conclusion API returned malformed outline point');
            }
            const content = String(point.content ?? '').trim();
            if (content) {
                rows.push({ time: formatTime(point.timestamp), content });
            }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Log the offending outline section (JSON.stringify) to identify the bad entry.
  2. Filter invalid sections instead of throwing: outline.filter(s => s && typeof s === 'object' && !Array.isArray(s)).
  3. Retry the conclusion request — malformed sections can be transient on Bilibili's side.
  4. Validate the whole outline shape right after fetching, before calling rowsFromModel.
  5. Check whether Bilibili introduced a new section schema your parser mis-maps.

Example fix

// before
for (const section of model.outline) {
    if (!section || typeof section !== 'object' || Array.isArray(section)) {
        throw new CommandExecutionError('Bilibili conclusion API returned malformed outline section');
    }
// after
for (const section of model.outline) {
    if (!section || typeof section !== 'object' || Array.isArray(section)) {
        console.warn('skipping malformed outline section', section);
        continue;
    }
Defensive patterns

Strategy: validation

Validate before calling

const validSections = (model?.outline ?? []).filter(
  s => s && typeof s === 'object' && !Array.isArray(s)
);
if (validSections.length !== (model?.outline ?? []).length) console.warn('some outline sections invalid');

Type guard

function isOutlineSection(s) {
  return !!s && typeof s === 'object' && !Array.isArray(s);
}

Try / catch

try {
  const rows = rowsFromModel(model);
} catch (e) {
  if (String(e.message).includes('malformed outline section')) {
    return [{ time: '', content: model.summary }];
  }
  throw e;
}

Prevention

When it happens

Trigger: An outline array contains a null element, a string/number, or a nested array — e.g. Bilibili emitted a placeholder entry, or the outline was constructed/deserialized incorrectly upstream.

Common situations: Partially generated AI outlines for new videos; API responses with sentinel null entries; custom pipelines feeding hand-parsed model objects into rowsFromModel.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/da54d91939f5c60d. Report an issue: GitHub.