jackwener/OpenCLI · error · CommandExecutionError

${label} returned malformed extraction payload

Error message

${label} returned malformed extraction payload

What it means

requireArrayEvaluateResult expects the evaluate payload to be an array. When the payload is neither an array nor an {error} object, it throws 'malformed extraction payload' prefixed with the extractor label, indicating the injected script returned an unexpected shape (null, string, number, or non-error object).

Source

Thrown at clis/weibo/utils.js:24

 * `page.evaluate` may return either the raw IIFE value or a
 * `{ session, data }` envelope depending on the browser-bridge version.
 * Adapter code that inspected the payload directly (e.g. `Array.isArray`,
 * truthiness checks on uid strings) silently received the envelope wrapper
 * instead of the inner value. This helper normalizes both shapes so callers
 * can keep their existing checks unchanged.
 */
export function unwrapEvaluateResult(payload) {
    if (payload && !Array.isArray(payload) && typeof payload === 'object' && 'session' in payload && 'data' in payload) {
        return payload.data;
    }
    return payload;
}
export function requireArrayEvaluateResult(payload, label) {
    if (!Array.isArray(payload)) {
        if (payload && typeof payload === 'object' && 'error' in payload) {
            throw new CommandExecutionError(`${label}: ${String(payload.error)}`);
        }
        throw new CommandExecutionError(`${label} returned malformed extraction payload`);
    }
    return payload;
}
export function requireObjectEvaluateResult(payload, label) {
    if (!payload || Array.isArray(payload) || typeof payload !== 'object') {
        throw new CommandExecutionError(`${label} returned malformed extraction payload`);
    }
    return payload;
}
/** Get the currently logged-in user's uid from Vue store or config API. */
export async function getSelfUid(page) {
    const uid = unwrapEvaluateResult(await page.evaluate(`
    (() => {
      const app = document.querySelector('#app')?.__vue_app__;
      const store = app?.config?.globalProperties?.$store;
      const uid = store?.state?.config?.config?.uid;
      if (uid) return String(uid);
      return null;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check which extractor (label in the message) returned the bad shape and log the raw payload during debugging.
  2. Verify you are logged in and landed on the expected page type before running extraction.
  3. Update the CLI to match current weibo.com markup.
  4. Harden the injected script to always return an array (possibly empty).

Example fix

// before
const list = document.querySelectorAll('.item');
return { found: list.length };
// after
return Array.from(document.querySelectorAll('.item')).map(el => ({ text: el.textContent }));
Defensive patterns

Strategy: type-guard

Validate before calling

if (!Array.isArray(payload)) throw new Error(`weibo: unexpected payload ${typeof payload}`);

Type guard

function isExtractionArray(p) {
  return Array.isArray(p) && p.every(x => x && typeof x === 'object');
}

Try / catch

try {
  const items = await rawDataCommand(label);
} catch (err) {
  if (err instanceof CommandExecutionError && /malformed/.test(err.message)) {
    // snapshot page / re-login / update selectors
  } else throw err;
}

Prevention

When it happens

Trigger: An injected extraction script returns null/undefined (selector not found and no error path taken), a scalar, or an unexpected object instead of an array; called via weibo data/rawData helpers.

Common situations: Weibo changed its DOM so the script's fallback return path is hit; the page is a redirect/login page; browser evaluate context was destroyed before the script finished.

Understand the failure class

Related errors


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