{"record":{"id":"907ba9ea654780e5","repo":"jackwener/OpenCLI","slug":"failed-to-export-generated-chatgpt-image-assets","errorCode":null,"errorMessage":"Failed to export generated ChatGPT image assets","messagePattern":"Failed to export generated ChatGPT image assets","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/chatgpt/image.js","lineNumber":151,"sourceCode":"        if (!convUrl) {\n            convUrl = await currentChatGPTLink(page);\n        }\n\n        const urls = await waitForChatGPTImages(page, beforeUrls, timeout, convUrl);\n        const link = convUrl;\n\n        if (!urls.length) {\n            throw new EmptyResultError('chatgpt image', `No generated images were detected before timeout. Open ${link} and verify whether ChatGPT finished generating the image.`);\n        }\n\n        if (skipDownload) {\n            return [{ status: '🎨 generated', file: '📁 -', link: `🔗 ${link}` }];\n        }\n\n        // Export and save images\n        const assets = await getChatGPTImageAssets(page, urls);\n        if (!assets.length) {\n            throw new CommandExecutionError('Failed to export generated ChatGPT image assets', `Open ${link} and verify the generated images are visible, then retry.`);\n        }\n\n        const stamp = Date.now();\n        const results = [];\n        for (let index = 0; index < assets.length; index += 1) {\n            const asset = assets[index];\n            const base64 = asset.dataUrl.replace(/^data:[^;]+;base64,/, '');\n            const suffix = assets.length > 1 ? `_${index + 1}` : '';\n            const ext = extFromMime(asset.mimeType);\n            const filePath = nextAvailablePath(outputDir, `chatgpt_${stamp}${suffix}`, ext);\n            await saveBase64ToFile(base64, filePath);\n            results.push({ status: '✅ saved', file: `📁 ${displayPath(filePath)}`, link: `🔗 ${link}` });\n        }\n        return results;\n    },\n});\n","sourceCodeStart":133,"sourceCodeEnd":168,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/chatgpt/image.js#L133-L168","documentation":"clis/chatgpt/image.js throws this CommandExecutionError when `getChatGPTImageAssets(page, urls)` returns an empty array after the image-generation page was opened. It means the automation could not locate or export any downloadable image assets for the generated result (selector drift, lazy-loaded images, or a failed generation).","triggerScenarios":"Running a `chatgpt image` command where the browser automation opens the result link, calls getChatGPTImageAssets, and the assets array comes back length 0.","commonSituations":"ChatGPT UI markup changed so image selectors no longer match; the generation actually failed server-side; images not yet rendered when scraped; slow network/proxy causing the gallery to never hydrate; user not logged in so a fallback page loaded.","solutions":["Open the result link manually and confirm images are visible, then retry the command.","Retry after waiting a few seconds so lazy-loaded images finish rendering.","Verify the ChatGPT session is logged in and images actually generated (check for a failure message in the conversation).","Update the CLI so getChatGPTImageAssets selectors match the current ChatGPT DOM."],"exampleFix":"// before\nconst assets = await getChatGPTImageAssets(page, urls);\nif (!assets.length) throw new CommandExecutionError('Failed to export generated ChatGPT image assets', ...);\n// after\nawait page.waitForSelector('img[src*=\"oaiusercontent\"], img[data-generated]', { timeout: 15000 });\nconst assets = await getChatGPTImageAssets(page, urls);\nif (!assets.length) throw new CommandExecutionError('Failed to export generated ChatGPT image assets', ...);","handlingStrategy":"retry","validationCode":"// Retry wrapper\nasync function exportWithRetry(page, urls, link, attempts = 3) {\n  for (let i = 0; i < attempts; i++) {\n    const assets = await getChatGPTImageAssets(page, urls);\n    if (assets.length) return assets;\n    await page.waitForTimeout(3000 * (i + 1));\n  }\n  throw new Error(`No assets exported; open ${link} to verify images are visible`);\n}","typeGuard":"function hasAssets(a) { return Array.isArray(a) && a.length > 0; }","tryCatchPattern":"try {\n  const assets = await getChatGPTImageAssets(page, urls);\n  if (!assets.length) throw new Error('no assets');\n} catch (err) {\n  console.error(`Open ${link} and verify images are visible, then retry.`);\n}","preventionTips":["Wait for image selectors to appear before scraping (waitForSelector).","Retry asset collection with backoff for lazy-loaded galleries.","Confirm generation succeeded before attempting export.","Keep scraping selectors updated against the current ChatGPT DOM."],"tags":["browser-automation","chatgpt","scraping","empty-result"],"backgroundTag":"automation-empty-result","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}