{"record":{"id":"44fce91271196e22","repo":"jackwener/OpenCLI","slug":"unsupported-image-format-ext-supported-jpg-44fce9","errorCode":null,"errorMessage":"Unsupported image format \"${ext}\". Supported: jpg, jpeg, png, gif, webp","messagePattern":"Unsupported image format \"(.+?)\"\\. Supported: jpg, jpeg, png, gif, webp","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/twitter/utils.js","lineNumber":47,"sourceCode":"    'image/gif': '.gif',\n    'image/webp': '.webp',\n};\n\n/**\n * Validate a single image path. Throws {@link ArgumentError} on bad input\n * (typed input failure surfaces before any browser interaction).\n *\n * @param {string} imagePath - Local filesystem path, may be relative.\n * @returns {string} Absolute resolved path.\n */\nexport function resolveImagePath(imagePath) {\n    const absPath = path.resolve(imagePath);\n    if (!fs.existsSync(absPath)) {\n        throw new ArgumentError(`Image file not found: ${absPath}`);\n    }\n    const ext = path.extname(absPath).toLowerCase();\n    if (!SUPPORTED_IMAGE_EXTENSIONS.has(ext)) {\n        throw new ArgumentError(`Unsupported image format \"${ext}\". Supported: jpg, jpeg, png, gif, webp`);\n    }\n    const stat = fs.statSync(absPath);\n    if (stat.size > MAX_IMAGE_SIZE_BYTES) {\n        throw new ArgumentError(`Image too large: ${(stat.size / 1024 / 1024).toFixed(1)} MB (max ${MAX_IMAGE_SIZE_BYTES / 1024 / 1024} MB)`);\n    }\n    return absPath;\n}\n\n/**\n * Resolve the file extension to use when persisting a remote image: prefer\n * Content-Type, fall back to URL pathname.\n */\nexport function resolveImageExtension(url, contentType) {\n    const normalizedContentType = (contentType || '').split(';')[0].trim().toLowerCase();\n    if (normalizedContentType && CONTENT_TYPE_TO_EXTENSION[normalizedContentType]) {\n        return CONTENT_TYPE_TO_EXTENSION[normalizedContentType];\n    }\n    try {","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/utils.js#L29-L65","documentation":"resolveImagePath checks the file extension against SUPPORTED_IMAGE_EXTENSIONS (.jpg, .jpeg, .png, .gif, .webp) — the formats the X composer accepts. Files with other extensions throw ArgumentError even if the content is a valid image. The check is extension-based, not content-based (no MIME sniffing).","triggerScenarios":"Passing a local file whose extension is not in the allowlist: .bmp, .tiff, .svg, .avif, .heic, or files with no/uppercase-mismatched extensions (case is normalized via toLowerCase, so .PNG is fine but .avif is rejected).","commonSituations":"iPhone HEIC photos; modern AVIF/WebP-variant downloads; SVG exports from design tools; screenshots saved as .bmp; files saved without any extension.","solutions":["Convert the image to a supported format (jpg/png/gif/webp), e.g. `magick input.heic output.jpg` or `sips -s format jpeg input.heic --out output.jpg`.","Rename the file with the correct extension if the content is already a supported format but misnamed (verify with `file image`).","For HEIC, export to JPEG from the Photos app or enable 'Most Compatible' camera format on iOS."],"exampleFix":"// before\nawait postWithImage('screenshot.bmp');\n// after: convert first\nimport { execSync } from 'node:child_process';\nexecSync('magick screenshot.bmp screenshot.png');\nawait postWithImage('screenshot.png');","handlingStrategy":"validation","validationCode":"const SUPPORTED = new Set(['.jpg', '.jpeg', '.png', '.gif', '.webp']);\nconst ext = path.extname(imagePath).toLowerCase();\nif (!SUPPORTED.has(ext)) {\n  throw new Error(`Convert ${ext || '(no extension)'} to jpg/png/gif/webp first`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await postWithImage(imagePath);\n} catch (err) {\n  if (err instanceof ArgumentError && /Unsupported image format/.test(err.message)) {\n    const converted = await convertToJpeg(imagePath); // e.g. magick\n    return postWithImage(converted);\n  }\n  throw err;\n}","preventionTips":["Convert HEIC/AVIF/BMP/SVG to jpg or png before uploading.","Verify actual format with `file <path>` — don't trust the extension alone for renamed files.","On iOS, set camera capture to 'Most Compatible' (JPEG) to avoid HEIC."],"tags":["input-validation","file-format","arguments"],"backgroundTag":"unsupported-file-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}