jackwener/OpenCLI · error · CommandExecutionError

${context}: malformed evaluate payload

Error message

${context}: malformed evaluate payload

What it means

requireObjectEvaluateResult unwraps a payload returned from a browser page.evaluate() call and enforces that it is a plain object. If the in-page script returned undefined, null, an array, or a primitive, the library throws this CommandExecutionError with the given context label, because evaluate results that fail to serialize (e.g. returning a DOM node or function) come back as undefined.

Source

Thrown at clis/douyin/_shared/evaluate-result.js:13

import { CommandExecutionError } from '@jackwener/opencli/errors';

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 requireObjectEvaluateResult(payload, context) {
  const result = unwrapEvaluateResult(payload);
  if (!result || Array.isArray(result) || typeof result !== 'object') {
    throw new CommandExecutionError(`${context}: malformed evaluate payload`);
  }
  return result;
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check the evaluate callback returns a plain object (e.g. return { ok: true, data }) rather than a raw value or nothing.
  2. Log the raw payload before requireObjectEvaluateResult to see what the page actually returned.
  3. Verify the page is still on the expected URL and not redirected/login-gated before evaluating.
  4. Fix the in-page extraction script if Douyin DOM/JS changes made it return early.

Example fix

// before
const payload = await page.evaluate(() => document.querySelector('.x')?.innerText);
const obj = requireObjectEvaluateResult(payload, 'extract');
// after
const payload = await page.evaluate(() => ({ text: document.querySelector('.x')?.innerText ?? null }));
const obj = requireObjectEvaluateResult(payload, 'extract');
Defensive patterns

Strategy: type-guard

Validate before calling

if (payload === undefined) console.error('evaluate returned undefined — non-serializable return or page navigated away');

Type guard

function isObjectPayload(v: unknown): v is Record<string, unknown> {
  return typeof v === 'object' && v !== null && !Array.isArray(v);
}
if (!isObjectPayload(raw)) throw new Error('unexpected evaluate payload');

Try / catch

try {
  const obj = requireObjectEvaluateResult(payload, 'extract');
} catch (e) {
  if (String(e.message).endsWith('malformed evaluate payload')) {
    console.error('page.evaluate must return a plain object; check the in-page script and current URL');
  }
  throw e;
}

Prevention

When it happens

Trigger: A page.evaluate() callback returns undefined (functions/DOM nodes don't serialize), returns null, an array, or a primitive instead of an object; the page navigated mid-evaluate so the script never completed.

Common situations: Douyin page DOM changed so the extraction script hits an early return; returning a non-serializable value from evaluate; script error swallowed and resolved with undefined; calling on a page that redirected away from creator.douyin.com.

Understand the failure class

Related errors


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