{"record":{"id":"31f4ab16859560c3","repo":"jackwener/OpenCLI","slug":"failed-to-upload-image-to-chatgpt","errorCode":null,"errorMessage":"Failed to upload image to ChatGPT","messagePattern":"Failed to upload image to ChatGPT","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/chatgpt/image.js","lineNumber":111,"sourceCode":"            throw new ArgumentError(preparedImages.reason);\n        }\n\n        // Navigate with full reload to clear React sidebar state before editing the draft.\n        if (kwargs.project) {\n            await navigateToProject(page, kwargs.project);\n        } else {\n            await page.goto(`https://${CHATGPT_DOMAIN}/new`, { settleMs: 2000 });\n        }\n        await clearChatGPTDraft(page);\n\n        if (imagePaths.length) {\n            let upload;\n            try {\n                upload = await uploadChatGPTImages(page, preparedImages.paths);\n            } catch (err) {\n                throw new CommandExecutionError(`Failed to upload image to ChatGPT: ${err instanceof Error ? err.message : String(err)}`);\n            }\n            if (!upload?.ok) throw new CommandExecutionError(upload?.reason || 'Failed to upload image to ChatGPT');\n        }\n\n        const beforeUrls = await getChatGPTVisibleImageUrls(page);\n\n        // Send an explicit generation/editing prompt so ChatGPT returns image assets.\n        const sent = await sendChatGPTMessage(page, buildPrompt(prompt, imagePaths.length));\n        if (!sent) {\n            throw new CommandExecutionError(\n                'Failed to send image prompt to ChatGPT',\n                `Open ${await currentChatGPTLink(page)} and verify the composer is ready.`,\n            );\n        }\n\n        // ChatGPT briefly navigates to /c/{id} after sending, then may\n        // redirect back to the home page. Poll until we capture the /c/ URL.\n        let convUrl = '';\n        for (let ci = 0; ci < 10; ci++) {\n            const url = await currentChatGPTLink(page);","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/chatgpt/image.js#L93-L129","documentation":"The non-exception counterpart to error 626: uploadChatGPTImages completed but returned { ok: false, reason }, and the command throws CommandExecutionError with that reason (or the generic 'Failed to upload image to ChatGPT' fallback when reason is missing). It indicates ChatGPT/the page reported the upload did not succeed.","triggerScenarios":"`opencli chatgpt image \"prompt\" --image <path>` where uploadChatGPTImages returns upload.ok === false — e.g. the attachment chip never appeared, ChatGPT rejected the file, or the upload timed out with a structured reason. If the helper returns undefined/null, the fallback message is thrown.","commonSituations":"Unsupported or oversized file rejected by ChatGPT; upload progress never confirmed before the helper's internal timeout; ChatGPT rate-limiting attachments; UI change so success detection fails and reason is undefined.","solutions":["Inspect upload?.reason in the message for the specific failure.","Verify the image renders and is under ChatGPT's size limits; convert exotic formats to PNG/JPG.","Retry — attachment uploads are frequently transient.","Test the same upload manually in the browser to see ChatGPT's rejection message.","If reason is the generic fallback repeatedly, update the library's upload/success-detection logic."],"exampleFix":"// before\nopencli chatgpt image \"edit\" --image ./diagram.tiff   # ChatGPT rejects format, ok:false\n// after\n# convert to a supported format\nmagick ./diagram.tiff ./diagram.png\nopencli chatgpt image \"edit\" --image ./diagram.png","handlingStrategy":"fallback","validationCode":"// Pre-validate format and size before asking ChatGPT to upload\nimport fs from 'node:fs';\nconst ok = (p) => ['png','jpg','jpeg','webp','gif'].includes(p.split('.').pop().toLowerCase())\n  && fs.statSync(p).size < 25 * 1024 * 1024;\nif (!ok(imagePath)) throw new Error(`Unsupported or oversized image: ${imagePath}`);","typeGuard":"null","tryCatchPattern":"try {\n  return await run('chatgpt image', prompt, '--image', imagePath);\n} catch (err) {\n  if (String(err.message).includes('Failed to upload image to ChatGPT')) {\n    // fallback: try a converted copy of the image\n    const converted = convertToPng(imagePath);\n    return run('chatgpt image', prompt, '--image', converted);\n  }\n  throw err;\n}","preventionTips":["Read upload?.reason surfaced in the error for the exact rejection","Convert exotic formats to PNG/JPG and compress oversized files first","Test the upload manually in the browser to see ChatGPT's own rejection message","Space out attachment uploads to avoid rate limiting","Fall back to prompt-only generation when the attachment is optional"],"tags":["chatgpt","upload","command-execution"],"backgroundTag":"image-upload-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}