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
- Re-run the export after confirming you are logged into grok.com in the automation browser (cookies valid, no login wall).
- Retry the command: transient navigation races can make an evaluate resolve with undefined.
- 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
- Assert the page is on grok.com and authenticated before running evaluate-based helpers.
- Handle Cloudflare/bot interstitials before scraping.
- Keep opencli updated; Grok DOM changes break injected script payload shapes.
- Have injected scripts return plain objects (never undefined) even when data is missing.
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
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- ${label} returned malformed rows
- Unexpected Amazon probe: ${JSON.stringify(probe)}
- Douyin search: unexpected evaluator payload shape
- Unexpected Rednote search extraction payload shape; expected
- Twitter lists returned an unexpected payload shape
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3706c3ff39467947.
Report an issue: GitHub.