jackwener/OpenCLI · error · CommandExecutionError

${label} returned a malformed payload

Error message

${label} returned a malformed payload

What it means

requireObjectEvaluateResult unwraps a browser page.evaluate() result (peeling off a {session, data} envelope if present) and asserts the payload is a non-null, non-array object. When the Grok page script returns null, undefined, a primitive, or an array, it throws CommandExecutionError('<label> returned a malformed payload', 'Expected an object payload from the Grok page.'). It is raised by state, waitForDiscordRoute, and waitForDiscordContent.

Source

Thrown at clis/grok/export-utils.js:21

export const GROK_CONVERSATION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

export function unwrapEvaluateResult(value) {
    if (
        value
        && typeof value === 'object'
        && !Array.isArray(value)
        && Object.hasOwn(value, 'session')
        && Object.hasOwn(value, 'data')
    ) {
        return value.data;
    }
    return value;
}

export function requireObjectEvaluateResult(value, label) {
    const payload = unwrapEvaluateResult(value);
    if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
        throw new CommandExecutionError(`${label} returned a malformed payload`, 'Expected an object payload from the Grok page.');
    }
    return payload;
}

export function requireBooleanEvaluateResult(value, label) {
    const payload = unwrapEvaluateResult(value);
    if (typeof payload !== 'boolean') {
        throw new CommandExecutionError(`${label} returned a malformed payload`, 'Expected a boolean payload from the Grok page.');
    }
    return payload;
}

function normalizeGrokUrl(value, id, makeError) {
    const fallback = `https://grok.com/c/${id}`;
    const raw = value == null || value === '' ? fallback : String(value);
    let parsed;
    try {
        parsed = new URL(raw);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-run the export after confirming you are logged into grok.com in the automation browser (cookies valid, no login wall).
  2. Retry the command: transient navigation races can make an evaluate resolve with undefined.
  3. If it persists on every run, update the opencli Grok scripts — the page DOM/API likely changed and the evaluate payload shape no longer matches.

Example fix

// before (site script can return undefined)
const data = await page.evaluate(() => document.querySelector('.conversation')?.dataset);
// after (guard to a plain object before requireObjectEvaluateResult)
const data = await page.evaluate(() => {
  const el = document.querySelector('.conversation');
  return el ? { ...el.dataset } : {};
});
Defensive patterns

Strategy: try-catch

Type guard

function isObjectPayload(v) {
  return v != null && typeof v === 'object' && !Array.isArray(v);
}

Try / catch

try {
  const state = await waitForDiscordRoute(page, route);
} catch (err) {
  if (err instanceof CommandExecutionError && err.message.includes('returned a malformed payload')) {
    // page DOM not in expected state: verify login/bot-check, then retry once
    await ensureGrokLoggedIn(page);
    return retry(() => waitForDiscordRoute(page, route), 1);
  }
  throw err;
}

Prevention

When it happens

Trigger: A page.evaluate call in the state/route/content helpers returns non-object data because the Grok DOM is not what the injected script expects (logged-out page, bot check/Cloudflare interstitial, UI redesign), the evaluation was interrupted and returned undefined, or the site script returns an array instead of an object.

Common situations: Grok ships a front-end redesign that changes the selectors/data shape the injected script reads; the session cookie expired so the page is a login screen whose script result is not the expected object; navigation raced the evaluate so it resolved with undefined.

Understand the failure class

Related errors


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