jackwener/OpenCLI · error · CommandExecutionError

${label} returned a malformed payload

Error message

${label} returned a malformed payload

What it means

requireObject in clis/bilibili/video.js validates that an API payload is a non-null, non-array object before field access. This CommandExecutionError fires when the Bilibili view/detail API returns anything else (null, array, primitive), typically inside the d and rights command handlers.

Source

Thrown at clis/bilibili/video.js:7

import { cli, Strategy } from '@jackwener/opencli/registry';
import { CommandExecutionError } from '@jackwener/opencli/errors';
import { apiGet, resolveBvid, parsePageArg, selectVideoPart } from './utils.js';

function requireObject(value, label) {
  if (!value || typeof value !== 'object' || Array.isArray(value)) {
    throw new CommandExecutionError(`${label} returned a malformed payload`);
  }
  return value;
}

function unwrapBrowserResult(value) {
  if (value && typeof value === 'object' && typeof value.session === 'string' && Object.hasOwn(value, 'data')) {
    return value.data;
  }
  return value;
}

function readOptionalFlag(value, label) {
  if (value == null) return false;
  if (typeof value === 'boolean') return value;
  if (typeof value === 'number') return value !== 0;
  throw new CommandExecutionError(`${label} returned a malformed flag`);
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-run the command with a fresh browser session (the CLI may require re-authentication)
  2. Retry later; risk-control interstitials are often transient
  3. Log the raw payload in the video command to see what Bilibili actually returned
  4. Update requireObject call sites in clis/bilibili/video.js if the API now legitimately wraps results differently

Example fix

// before
const d = requireObject(payload.data, 'Bilibili view API data');
// after
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
  throw new CommandExecutionError(`Bilibili view API returned unexpected body: ${JSON.stringify(payload).slice(0, 200)}`);
}
const d = requireObject(payload.data, 'Bilibili view API data');
Defensive patterns

Strategy: type-guard

Validate before calling

// confirm a healthy browser session exists before invoking video commands
if (!session || !session.page) throw new Error('start a browser session first');

Type guard

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

Try / catch

try { await runVideoCommand(args); }
catch (e) {
  if (e instanceof CommandExecutionError && e.message.includes('malformed payload')) { console.error('Non-object API response; retry with fresh session'); }
  else throw e;
}

Prevention

When it happens

Trigger: apiGet resolves to null/undefined, an array, or a string — e.g. the browser session returned an HTML page, an anti-bot interstitial, or the API replied with a non-object error body.

Common situations: Bilibili serving a risk-control/captcha page; session expired so the fetch returns a login redirect; API schema change wrapping data differently; empty response on transient server errors.

Understand the failure class

Related errors


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