{"record":{"id":"3706c3ff39467947","repo":"jackwener/OpenCLI","slug":"label-returned-a-malformed-payload-3706c3","errorCode":null,"errorMessage":"${label} returned a malformed payload","messagePattern":"(.+?) returned a malformed payload","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/grok/export-utils.js","lineNumber":21,"sourceCode":"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;\n\nexport function unwrapEvaluateResult(value) {\n    if (\n        value\n        && typeof value === 'object'\n        && !Array.isArray(value)\n        && Object.hasOwn(value, 'session')\n        && Object.hasOwn(value, 'data')\n    ) {\n        return value.data;\n    }\n    return value;\n}\n\nexport function requireObjectEvaluateResult(value, label) {\n    const payload = unwrapEvaluateResult(value);\n    if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {\n        throw new CommandExecutionError(`${label} returned a malformed payload`, 'Expected an object payload from the Grok page.');\n    }\n    return payload;\n}\n\nexport function requireBooleanEvaluateResult(value, label) {\n    const payload = unwrapEvaluateResult(value);\n    if (typeof payload !== 'boolean') {\n        throw new CommandExecutionError(`${label} returned a malformed payload`, 'Expected a boolean payload from the Grok page.');\n    }\n    return payload;\n}\n\nfunction normalizeGrokUrl(value, id, makeError) {\n    const fallback = `https://grok.com/c/${id}`;\n    const raw = value == null || value === '' ? fallback : String(value);\n    let parsed;\n    try {\n        parsed = new URL(raw);","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/grok/export-utils.js#L3-L39","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (site script can return undefined)\nconst data = await page.evaluate(() => document.querySelector('.conversation')?.dataset);\n// after (guard to a plain object before requireObjectEvaluateResult)\nconst data = await page.evaluate(() => {\n  const el = document.querySelector('.conversation');\n  return el ? { ...el.dataset } : {};\n});","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isObjectPayload(v) {\n  return v != null && typeof v === 'object' && !Array.isArray(v);\n}","tryCatchPattern":"try {\n  const state = await waitForDiscordRoute(page, route);\n} catch (err) {\n  if (err instanceof CommandExecutionError && err.message.includes('returned a malformed payload')) {\n    // page DOM not in expected state: verify login/bot-check, then retry once\n    await ensureGrokLoggedIn(page);\n    return retry(() => waitForDiscordRoute(page, route), 1);\n  }\n  throw err;\n}","preventionTips":["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."],"tags":["browser-automation","payload-shape","dom-scraping"],"backgroundTag":"unexpected-payload-shape","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}