{"record":{"id":"852fa2997741e869","repo":"jackwener/OpenCLI","slug":"warn-image-base64-payload-is-base64-length","errorCode":null,"errorMessage":"[warn] Image base64 payload is ${(base64.length / 1024 / 1024).toFixed(1)}MB. This may fail with the browser bridge. Update the extension to v1.6+ for CDP-based upload, or compress the image before attaching.","messagePattern":"\\[warn\\] Image base64 payload is (.+?)MB\\. This may fail with the browser bridge\\. Update the extension to v1\\.6\\+ for CDP-based upload, or compress the image before attaching\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"clis/twitter/utils.js","lineNumber":155,"sourceCode":"            const msg = err instanceof Error ? err.message : String(err);\n            if (!isRecoverableFileInputError(msg)) {\n                throw new Error(`Image upload failed: ${msg}`);\n            }\n            // setFileInput not supported by extension — fall through to base64 fallback.\n        }\n    }\n    if (!uploaded) {\n        const ext = path.extname(absImagePath).toLowerCase();\n        const mimeType = ext === '.png'\n            ? 'image/png'\n            : ext === '.gif'\n                ? 'image/gif'\n                : ext === '.webp'\n                    ? 'image/webp'\n                    : 'image/jpeg';\n        const base64 = fs.readFileSync(absImagePath).toString('base64');\n        if (base64.length > 500_000) {\n            console.warn(`[warn] Image base64 payload is ${(base64.length / 1024 / 1024).toFixed(1)}MB. ` +\n                'This may fail with the browser bridge. Update the extension to v1.6+ for CDP-based upload, ' +\n                'or compress the image before attaching.');\n        }\n        const upload = await page.evaluate(`\n      (() => {\n        const input = document.querySelector(${JSON.stringify(fileInputSelector)});\n        if (!input) return { ok: false, error: 'No file input found on page' };\n\n        const binary = atob(${JSON.stringify(base64)});\n        const bytes = new Uint8Array(binary.length);\n        for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n\n        const dt = new DataTransfer();\n        const blob = new Blob([bytes], { type: ${JSON.stringify(mimeType)} });\n        dt.items.add(new File([blob], ${JSON.stringify(path.basename(absImagePath))}, { type: ${JSON.stringify(mimeType)} }));\n\n        let assigned = false;\n        try {","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/utils.js#L137-L173","documentation":"attachComposerImage warns when the base64-encoded image read from disk exceeds ~500KB, because large payloads may fail when injected through the browser bridge's page.evaluate path. Older extensions (< v1.6) lack CDP-based upload, so big attachments can silently fail or time out.","triggerScenarios":"Attaching an image whose base64 string length > 500,000 characters (roughly a source file over ~375KB) via clis/twitter attach-image with a pre-v1.6 extension.","commonSituations":"Attaching high-resolution photos or uncompressed screenshots, GIFs several MB in size, older browser extension installed, images not pre-optimized before attach.","solutions":["Update the browser extension to v1.6+ for CDP-based upload which handles large payloads","Compress/resize the image before attaching (e.g., convert to JPEG/WebP, scale to ≤1600px)","If the attach then fails, retry after compressing rather than increasing timeouts","Check the extension version in the browser and reload it if outdated"],"exampleFix":"// before\nnpx sharp -i photo.png -o photo-small.jpg resize 1280\nopencli twitter attach-image photo-small.jpg\n// after (compressed)\n# attach the compressed file\nopencli twitter attach-image photo-small.jpg","handlingStrategy":"validation","validationCode":"const stat = fs.statSync(absImagePath);\nif (stat.size > 375 * 1024) {\n  console.warn('Image too large for browser bridge; compress first.');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await attachComposerImage(page, imagePath);\n} catch (err) {\n  if (err instanceof CliError && /upload|payload/i.test(err.message)) {\n    await attachComposerImage(page, compressImage(imagePath)); // retry compressed\n  }\n}","preventionTips":["Compress/resize images to under ~375KB before attaching","Update the browser extension to v1.6+ (CDP-based upload)","Prefer JPEG/WebP over PNG for photos","Watch for the '[warn] Image base64 payload' line and treat it as a signal to compress"],"tags":["payload-size","base64","browser-bridge","twitter","image-upload"],"backgroundTag":"payload-too-large","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}