jackwener/OpenCLI · error · CommandExecutionError

Bilibili ${label} API returned a malformed payload

Error message

Bilibili ${label} API returned a malformed payload

What it means

CommandExecutionError thrown by requireOkPayload when the Bilibili API response is not an object with a numeric 'code' field — i.e. the response envelope itself is missing or unrecognizable. This library expects Bilibili's standard {code, message, data} envelope on every /x/web-interface/view, /x/v2/reply/main, or /x/v2/reply/reply call.

Source

Thrown at clis/bilibili/comments.js:38

        throw new ArgumentError(`bilibili comments limit must be an integer between 1 and ${MAX_LIMIT}`);
    }
    return limit;
}

function parseParent(value) {
    if (value == null) {
        return null;
    }
    const parent = Number(value);
    if (!Number.isInteger(parent) || parent <= 0) {
        throw new ArgumentError('bilibili comments parent must be a positive integer rpid');
    }
    return parent;
}

function requireOkPayload(payload, label) {
    if (!payload || typeof payload !== 'object' || Array.isArray(payload) || !Object.hasOwn(payload, 'code')) {
        throw new CommandExecutionError(`Bilibili ${label} API returned a malformed payload`);
    }
    if (payload.code !== 0) {
        const message = payload.message ?? 'unknown error';
        if (isAuthLikeBilibiliError(payload.code, message)) {
            throw new AuthRequiredError('bilibili.com', `Bilibili ${label} API requires login or permission: ${message} (${payload.code})`);
        }
        throw new CommandExecutionError(`Bilibili ${label} API failed: ${message} (${payload.code})`);
    }
    return payload.data;
}

function requireReplies(data, label) {
    if (!data || typeof data !== 'object' || Array.isArray(data)) {
        throw new CommandExecutionError(`Bilibili ${label} API returned malformed data`);
    }
    if (!Object.hasOwn(data, 'replies')) {
        throw new CommandExecutionError(`Bilibili ${label} API did not return replies`);
    }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-login / refresh the browser cookie session (the CLI uses Strategy.COOKIE) and retry
  2. Fetch the URL manually in the page to inspect what the API actually returned
  3. Check for Bilibili risk-control or maintenance, wait and retry later
  4. Update the library in case Bilibili changed the response envelope

Example fix

// before (raw fetch assuming envelope)
const payload = JSON.parse(await res.text());
// after
const body = JSON.parse(await res.text());
if (!body || typeof body !== 'object' || !('code' in body)) throw new Error('unexpected bilibili response: ' + await res.clone().text().catch(() => 'n/a'));
Defensive patterns

Strategy: retry

Validate before calling

null

Type guard

function isBiliEnvelope(x) { return !!x && typeof x === 'object' && !Array.isArray(x) && Object.hasOwn(x, 'code'); }

Try / catch

try { const rows = await run(['bilibili','comments',bvid]); } catch (e) { if (/malformed payload/.test(e.message)) { await refreshSession(); return retryWithBackoff(fn, 2); } throw e; }

Prevention

When it happens

Trigger: The view/reply API returned HTML (e.g. a login page, risk-control intercept, or CDN error page), an empty body, an array, or JSON without a 'code' key instead of the standard envelope.

Common situations: Bilibili risk control (captcha/anti-bot) intercepting the cookie-based request; expired session causing an HTML redirect; network middleboxes or proxies returning error pages; Bilibili API contract changes.

Understand the failure class

Related errors


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