{"record":{"id":"78ca10955f40a9ef","repo":"jackwener/OpenCLI","slug":"no-finished-image-appeared-before-timeout-re-run","errorCode":null,"errorMessage":"No finished image appeared before timeout. Re-run with a higher --timeout if it is still generating.","messagePattern":"No finished image appeared before timeout\\. Re-run with a higher --timeout if it is still generating\\.","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"error","filePath":"clis/chatgpt/utils.js","lineNumber":2724,"sourceCode":"        if (urls.length === 0) continue;\n\n        const key = urls.join('\\n');\n        const prevKey = lastUrls.join('\\n');\n        if (key === prevKey) {\n            stableCount += 1;\n        } else {\n            lastUrls = urls;\n            stableCount = 1;\n        }\n\n        if (stableCount >= 2 || i === maxPolls - 1) {\n            return lastUrls;\n        }\n    }\n    // A deadline that lands while ChatGPT is visibly mid-generation is a\n    // temporary failure, not an empty conversation. Mirror the ask wait.\n    if (!lastUrls.length && stillRendering) {\n        throw new TimeoutError(\n            'chatgpt image',\n            timeoutSeconds,\n            'No finished image appeared before timeout. Re-run with a higher --timeout if it is still generating.',\n        );\n    }\n    return lastUrls;\n}\n\n/**\n * Get the list of ChatGPT Projects from the sidebar.\n * Navigates to chatgpt.com if not already there, opens the sidebar,\n * and extracts project links (matching /g/g-p-*).\n */\nexport async function getProjectList(page) {\n    await ensureOnChatGPT(page);\n\n    // Ensure sidebar is open\n    const openSidebar = requireBooleanEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {","sourceCodeStart":2706,"sourceCodeEnd":2742,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/chatgpt/utils.js#L2706-L2742","documentation":"TimeoutError for image generation: the loop collects finished image URLs, and if at deadline the page was still visibly rendering and zero finished images had appeared, the library treats it as a temporary in-progress failure and throws.","triggerScenarios":"chatgpt image wait reached timeoutSeconds while stillRendering was true and lastUrls was empty — the image generation never completed within the window.","commonSituations":"Complex image prompts taking longer than --timeout; ChatGPT image service congestion; user lowered the timeout too aggressively; generation stalled showing a shimmer/spinner indefinitely.","solutions":["Re-run with a higher --timeout (image jobs can queue for minutes)","Check the conversation manually — if the image finished after the deadline, scrape the URL directly","Retry the request; a queued/stalled job often succeeds on a second attempt","Reduce prompt complexity or request fewer images per prompt"],"exampleFix":"// before\nawait chatgptImage(page, prompt);              // default timeout\n// after\nawait chatgptImage(page, prompt, { timeout: 600 }); // 10 min","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await waitForChatGPTImages(page, { timeoutSeconds: 180 });\n} catch (e) {\n  if (e instanceof TimeoutError && e.operation === 'chatgpt image') {\n    // retry once with timeoutSeconds: 600\n  } else throw e;\n}","preventionTips":["Allow several minutes for image generation, more under load","Check the conversation for finished images that landed just after the deadline","Simplify prompts / request fewer images to shorten generation time"],"tags":["timeout","chatgpt","image-generation"],"backgroundTag":"operation-timed-out","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}