jackwener/OpenCLI · error · CommandExecutionError
Bilibili creator comparison API returned a malformed envelop
Error message
Bilibili creator comparison API returned a malformed envelope
What it means
requirePayload validates the JSON body returned by Bilibili's undocumented archive_diagnose/compare endpoint before any field is read. A 'malformed envelope' means the parsed body was not an object, or had no safe-integer `code` field, so the standard Bilibili response contract (code/message/data) could not be trusted at all. The library throws this rather than guessing at an unparseable shape, because the endpoint is internal-unstable and PAGE_FETCH-based.
Source
Thrown at clis/bilibili/creator-stats.js:50
{ metric: 'thumbnailClickPct', key: 'tm_rate', unit: 'percent', divisor: 100 },
{ metric: 'threeSecondExitPct', key: 'crash_rate', unit: 'percent', divisor: 100 },
{ metric: 'interactionPct', key: 'interact_rate', unit: 'percent', divisor: 100 },
{ metric: 'playToFollowerPct', key: 'play_trans_fan_rate', unit: 'percent', divisor: 100 },
];
function isRecord(value) {
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
}
function isAuthLike(code, message) {
return code === -101
|| code === -111
|| /登录|账号未登录|login required|not logged in/i.test(String(message ?? ''));
}
function requirePayload(payload) {
if (!isRecord(payload) || !Number.isSafeInteger(payload.code)) {
throw new CommandExecutionError('Bilibili creator comparison API returned a malformed envelope');
}
const message = String(payload.message ?? payload.msg ?? 'unknown error');
if (payload.code !== 0) {
if (isAuthLike(payload.code, message)) {
throw new AuthRequiredError('member.bilibili.com', `Bilibili creator-center login is required: ${message}`);
}
throw new CommandExecutionError(`Bilibili creator comparison API failed: ${message} (${payload.code})`);
}
if (!isRecord(payload.data) || !Array.isArray(payload.data.list)) {
throw new CommandExecutionError('Bilibili creator comparison API returned malformed list data');
}
return payload.data.list;
}
async function fetchComparison(page) {
try {
const payload = await page.fetchJson(
`${MEMBER_ORIGIN}/x/web/data/archive_diagnose/compare?size=100`,View on GitHub (pinned to 49907e53dc)
Solutions
- Log in to the Bilibili creator center (member.bilibili.com) in the browser session the CLI reuses so a valid session envelope is returned
- Re-run after completing any captcha/verification challenge in the browser, then retry the command
- Check whether Bilibili changed the endpoint response shape and update the whitelist/parse logic in requirePayload
- Inspect the raw response (log payload) to confirm whether it is HTML, an interstitial, or a new JSON shape
Example fix
// before: blindly calling the command with a stale session $ opencli bilibili creator-stats BV1xx411c7mD CommandExecutionError: Bilibili creator comparison API returned a malformed envelope // after: refresh the creator-center login first $ # open member.bilibili.com in the browser, log in, then: $ opencli bilibili creator-stats BV1xx411c7mD
Defensive patterns
Strategy: type-guard
Validate before calling
const res = await fetch('https://member.bilibili.com/x/web/data/archive_diagnose/compare?size=100', { headers: { cookie } });
const ct = res.headers.get('content-type') || '';
if (!ct.includes('application/json')) throw new Error('non-JSON response — session likely invalid'); Type guard
function isBilibiliEnvelope(p) {
return Boolean(p) && typeof p === 'object' && !Array.isArray(p) && Number.isSafeInteger(p.code);
} Try / catch
try {
const rows = await runCommand();
} catch (e) {
if (/malformed envelope/.test(e.message)) {
// prompt interactive login / check for anti-bot interstitial, then retry once
} else throw e;
} Prevention
- Keep the browser session logged into member.bilibili.com before invoking the command
- Complete any captcha/security challenge in the browser before running headless requests
- Watch for Bilibili endpoint schema changes and pin fixtures to detect drift early
When it happens
Trigger: page.fetchJson on https://member.bilibili.com/x/web/data/archive_diagnose/compare?size=100 returns JSON that is an array, a string, a number, null, or an object whose `code` is missing or not a safe integer (e.g. an HTML login page parsed as something else, a WAF/interstitial JSON, or a contract change by Bilibili).
Common situations: Expired or missing cookie session causing member.bilibili.com to return a non-standard body; Bilibili serving an anti-bot/verification interstitial; a Bilibili-side schema change to the undocumented endpoint; a proxy or captive portal intercepting the request.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Bilibili creator comparison API returned malformed list data
- Bilibili creator comparison
- Bilibili creator comparison request failed: ${detail}
- Bilibili creator comparison returned a malformed manuscript
- Bilibili creator comparison returned duplicate rows for ${bv
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/c20a84d9495ae5c4.
Report an issue: GitHub.