jackwener/OpenCLI · error · CommandExecutionError

Bilibili ${label} API returned a malformed payload

Error message

Bilibili ${label} API returned a malformed payload

What it means

requireOkPayload enforces that a Bilibili API response is a non-null, non-array object containing a `code` field before interpreting it. If the body does not have this shape, the library cannot tell success from failure and throws instead of dereferencing undefined fields.

Source

Thrown at clis/bilibili/utils.js:228

      const res = await fetch(${urlJs}, { credentials: "include" });
      return await res.json();
    }
  `);
}
/**
 * Bilibili write APIs return a JSON envelope `{ code, message, data }`. A non-zero
 * `code` carries either an auth/permission failure (login expired, CSRF rejected,
 * forbidden) or an application-level error (rate limit, validation, etc.). These
 * two helpers route the envelope to the right typed error so every write adapter
 * surfaces login problems as `AuthRequiredError`, not a generic execution error.
 */
export function isAuthLikeBilibiliError(code, message) {
    return code === -101 || code === -111 || code === -403 || /csrf|登录|账号|权限|forbidden|permission|login/i.test(String(message ?? ''));
}

export 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;
}

/**
 * POST form-encoded params to a Bilibili API endpoint.
 * Runs inside the logged-in browser context and auto-attaches the bili_jct CSRF token,
 * which Bilibili requires on every authenticated write request.
 */
export async function apiPost(page, path, opts = {}) {
    const params = opts.params ?? {};

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Log the raw HTTP status and body — if it's HTML, you were likely blocked by risk control; slow down or send proper headers/cookies.
  2. Ensure the response was parsed with response.json() and that parsing succeeded before calling requireOkPayload.
  3. Check that requests include a realistic User-Agent and Referer; missing headers often trigger non-JSON block pages.
  4. If a proxy/CDN is interfering, retry or route around it; verify the endpoint URL is correct.

Example fix

// before
const payload = await res.text(); // string, not parsed JSON
requireOkPayload(payload, 'view');
// after
const payload = await res.json();
requireOkPayload(payload, 'view');
Defensive patterns

Strategy: try-catch

Validate before calling

const text = await res.text();
let payload; try { payload = JSON.parse(text); } catch { throw new Error(`Non-JSON Bilibili response (HTTP ${res.status}): ${text.slice(0,200)}`); }

Type guard

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

Try / catch

try { const data = requireOkPayload(payload, 'view'); } catch (e) { if (/malformed payload/.test(e.message)) { logRawBody(); /* likely anti-bot HTML or unparsed body */ } throw e; }

Prevention

When it happens

Trigger: Passing a payload to requireOkPayload(payload, label) that is null, undefined, an Array, a primitive, or an object without a `code` property — e.g., raw fetch text never parsed as JSON, an HTML error page, or an empty 204 body.

Common situations: Bilibili returning an HTML anti-bot/risk-control page (HTTP 412/403) with a non-JSON body; response.json() failing upstream and null being passed along; a WAF/CDN block page; network middleware returning empty bodies on 304.

Understand the failure class

Related errors


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