{"record":{"id":"701ef306543e80e3","repo":"jackwener/OpenCLI","slug":"failed-to-upload-image-to-chatgpt-err-instanceo","errorCode":null,"errorMessage":"Failed to upload image to ChatGPT: ${err instanceof Error ? err.message : String(err)}","messagePattern":"Failed to upload image to ChatGPT: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/chatgpt/image.js","lineNumber":109,"sourceCode":"        const preparedImages = imagePaths.length ? await prepareChatGPTImagePaths(imagePaths) : { ok: true, paths: [] };\n        if (!preparedImages.ok) {\n            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 = '';","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/chatgpt/image.js#L91-L127","documentation":"uploadChatGPTImages threw inside the command, so it is wrapped into a CommandExecutionError prefixed 'Failed to upload image to ChatGPT: <underlying message>'. This is the exception path (as opposed to the {ok:false} path of error 627) — the upload helper itself raised, e.g. the attachment button/input was not found or a DOM interaction failed.","triggerScenarios":"`opencli chatgpt image \"prompt\" --image <path>` where uploadChatGPTImages(page, preparedImages.paths) throws — composer not rendered, attachment file input missing, page navigated mid-upload, or a Playwright/DOM error during the upload interaction.","commonSituations":"ChatGPT UI changed so the upload control selector is stale; page not fully hydrated when upload starts; file too large triggering a ChatGPT-side error that surfaces as an exception; transient network failure during upload; composer in an unexpected state (leftover draft or dialog).","solutions":["Read the suffixed underlying message — it identifies the failing DOM step.","Retry the command; transient composer/hydration issues often clear on a second run.","Verify the composer is visible and usable in a browser session first.","Check file size/format against ChatGPT upload limits.","If it fails consistently, the upload selectors likely changed — update the library."],"exampleFix":"// before\nopencli chatgpt image \"enhance\" --image ./big-50mb.png   # upload throws mid-flight\n// after\n# resize/compress the image below ChatGPT limits, then\nopencli chatgpt image \"enhance\" --image ./resized.png","handlingStrategy":"try-catch","validationCode":"// Warm up the composer before uploading: navigate and confirm the page is interactive\nawait run('chatgpt image', prompt, '--image', path); // wrap with retry below","typeGuard":"null","tryCatchPattern":"async function uploadWithRetry(cmd, attempt = 0) {\n  try {\n    return await run('chatgpt image', cmd.prompt, '--image', cmd.image);\n  } catch (err) {\n    const msg = String(err.message);\n    if (msg.includes('Failed to upload image to ChatGPT:') && attempt < 2) {\n      await sleep(15_000 * (attempt + 1));\n      return uploadWithRetry(cmd, attempt + 1);\n    }\n    throw err;\n  }\n}","preventionTips":["Retry transient upload failures with backoff","Keep image files under ChatGPT's size limits and in supported formats","Ensure the persistent browser session is healthy and freshly logged in","Check the wrapped underlying message — it names the failing step","Update the library if the upload control selectors drift after UI changes"],"tags":["chatgpt","upload","dom-extraction","command-execution"],"backgroundTag":"image-upload-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}