{"record":{"id":"1bffe3459a91c168","repo":"jackwener/OpenCLI","slug":"gemini-image-export-returned-a-malformed-result","errorCode":null,"errorMessage":"Gemini image export returned a malformed result","messagePattern":"Gemini image export returned a malformed result","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/gemini/utils.js","lineNumber":2509,"sourceCode":"        // any truthy string: an HTML error body reaches here as text/html, and\n        // an empty canvas export as a payload-less data URL (#2245).\n        if (/^data:[^;,]+;base64,[A-Za-z0-9+/]+=*$/.test(dataUrl) && String(mimeType).startsWith('image/')) {\n          results.push({ url: String(targetUrl), dataUrl, mimeType, width, height });\n        }\n      }\n\n      return results;\n    })(${urlsJson})\n  `);\n    const assets = requireGeminiArrayResult(result, 'Gemini image export');\n    for (const asset of assets) {\n        if (!isObjectRecord(asset)\n            || typeof asset.url !== 'string'\n            || typeof asset.dataUrl !== 'string'\n            || !/^data:[^;,]+;base64,[A-Za-z0-9+/]+=*$/.test(asset.dataUrl)\n            || typeof asset.mimeType !== 'string'\n            || !asset.mimeType.startsWith('image/')) {\n            throw new CommandExecutionError('Gemini image export returned a malformed result');\n        }\n    }\n    return assets;\n}\nexport async function waitForGeminiResponse(page, baseline, promptText, timeoutSeconds) {\n    if (timeoutSeconds <= 0)\n        return '';\n    // Reply ownership must survive Gemini prepending older history later.\n    // Re-anchor on the submitted user turn when possible, and otherwise only\n    // accept assistants that are appended to the exact submission snapshot.\n    const pickStructuredReplyCandidate = (current) => {\n        if (!current.structuredTurnsTrusted)\n            return '';\n        const userAnchorTurnIndex = findLastMatchingGeminiTurnIndex(current.turns, baseline.userAnchorTurn);\n        if (userAnchorTurnIndex !== null) {\n            const candidate = current.turns\n                .slice(userAnchorTurnIndex + 1)\n                .filter((turn) => turn.Role === 'Assistant')","sourceCodeStart":2491,"sourceCodeEnd":2527,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/gemini/utils.js#L2491-L2527","documentation":"CommandExecutionError thrown during Gemini image export when an in-page asset record fails structural validation. The library requires each asset to be an object with string url, string dataUrl matching a strict data:image/...;base64 pattern, and an image/* mimeType; anything else is treated as a malformed export result.","triggerScenarios":"The page.evaluate-based export script in clis/gemini/utils.js:2509 returns an asset that is not an object, lacks url/dataUrl/mimeType, has a non-image mimeType, or whose dataUrl is not valid base64 data URI form.","commonSituations":"Gemini DOM changes altering the shape of the export payload; partial page load; bot-detection or consent screens injecting unexpected DOM; automation running against an outdated Gemini UI layout.","solutions":["Re-run the export after confirming the Gemini page fully loaded","Update the CLI to a version matching the current Gemini DOM","Log/dump the raw evaluate result to inspect the actual asset shape"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"function isValidAsset(a) {\n  return !!a && typeof a === 'object'\n    && typeof a.url === 'string'\n    && typeof a.dataUrl === 'string'\n    && /^data:[^;,]+;base64,[A-Za-z0-9+/]+=*$/.test(a.dataUrl)\n    && typeof a.mimeType === 'string'\n    && a.mimeType.startsWith('image/');\n}","typeGuard":"function isImageAsset(a): a is { url: string; dataUrl: string; mimeType: string } {\n  return typeof a === 'object' && a !== null\n    && typeof (a as any).url === 'string'\n    && typeof (a as any).dataUrl === 'string'\n    && /^data:[^;,]+;base64,[A-Za-z0-9+/]+=*$/.test((a as any).dataUrl)\n    && typeof (a as any).mimeType === 'string'\n    && (a as any).mimeType.startsWith('image/');\n}","tryCatchPattern":"try {\n  const assets = await exportGeminiImages(page, urls);\n} catch (err) {\n  if (err.message.includes('malformed result')) {\n    console.error('Gemini DOM changed or page not fully loaded; re-run after full load or update CLI');\n  }\n  throw err;\n}","preventionTips":["Wait for the page to fully render before exporting","Keep the CLI updated against Gemini UI changes","Validate returned assets yourself before consuming them"],"tags":["validation","browser-automation","gemini"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}