{"record":{"id":"b7756e5c107d9d3f","repo":"jackwener/OpenCLI","slug":"unsupported-media-format-ext","errorCode":null,"errorMessage":"Unsupported media format: ${ext}","messagePattern":"Unsupported media format: (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/instagram/post.js","lineNumber":109,"sourceCode":"    if (inputs.length > MAX_MEDIA_ITEMS) {\n        throw new ArgumentError(`Too many media items: ${inputs.length}`, `Instagram carousel posts support at most ${MAX_MEDIA_ITEMS} items`);\n    }\n    const items = inputs.map((input) => {\n        const resolved = path.resolve(String(input || '').trim());\n        if (!resolved) {\n            throw new ArgumentError('Media path cannot be empty');\n        }\n        if (!fs.existsSync(resolved)) {\n            throw new ArgumentError(`Media file not found: ${resolved}`);\n        }\n        const ext = path.extname(resolved).toLowerCase();\n        if (SUPPORTED_IMAGE_EXTENSIONS.has(ext)) {\n            return { type: 'image', filePath: resolved };\n        }\n        if (SUPPORTED_VIDEO_EXTENSIONS.has(ext)) {\n            return { type: 'video', filePath: resolved };\n        }\n        throw new ArgumentError(`Unsupported media format: ${ext}`, 'Supported formats: images (.jpg, .jpeg, .png, .webp) and videos (.mp4)');\n    });\n    return items;\n}\nfunction normalizePostMediaItems(kwargs) {\n    const media = String(kwargs.media ?? '').trim();\n    return validateMixedMediaItems(media.split(',').map((part) => part.trim()).filter(Boolean));\n}\nfunction validateInstagramPostArgs(kwargs) {\n    const media = kwargs.media;\n    if (media === undefined) {\n        throw new ArgumentError('Argument \"media\" is required.', 'Provide --media /path/to/file.jpg or --media /path/a.jpg,/path/b.mp4');\n    }\n}\nfunction isSafePrivateRouteFallbackError(error) {\n    if (!(error instanceof CommandExecutionError))\n        return false;\n    return error.message.startsWith('Instagram private publish')\n        || error.message.startsWith('Instagram private route');","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/instagram/post.js#L91-L127","documentation":"After confirming the media file exists, validateMixedMediaItems checks its lowercase extension against SUPPORTED_IMAGE_EXTENSIONS (.jpg/.jpeg/.png/.webp) and SUPPORTED_VIDEO_EXTENSIONS (.mp4). Any other extension throws ArgumentError with the offending extension and a hint listing supported formats. Extension, not MIME type, is the sole discriminator.","triggerScenarios":"Passing --media with a file whose extension is .gif, .mov, .avi, .heic, .bmp, or a file with no extension at all — even if the actual content is a supported image/video.","commonSituations":"iPhone HEIC photos; screen recordings saved as .mov; GIFs users expect Instagram to accept; renamed files that lost their extension; double extensions like photo.jpg.txt.","solutions":["Convert the file: images to .jpg/.png/.webp, videos to .mp4 (e.g. ffmpeg -i clip.mov clip.mp4)","Rename the file so its extension matches its true format if it is actually supported","For HEIC use sips -s format jpeg photo.heic --out photo.jpg (macOS) or ImageMagick convert","Do not try .gif; Instagram carousels via this CLI do not accept it"],"exampleFix":"// before\n--media /photos/clip.mov\n// after (shell)\nffmpeg -i /photos/clip.mov -c:v libx264 /photos/clip.mp4\n--media /photos/clip.mp4","handlingStrategy":"validation","validationCode":"const SUPPORTED = new Set(['.jpg', '.jpeg', '.png', '.webp', '.mp4']);\nfunction assertSupportedMedia(media) {\n  for (const p of String(media).split(',').map(s => s.trim()).filter(Boolean)) {\n    const ext = path.extname(p).toLowerCase();\n    if (!SUPPORTED.has(ext)) throw new Error(`Unsupported media format: ${ext} (${p})`);\n  }\n}\nassertSupportedMedia(media);","typeGuard":"function hasSupportedExtension(p) {\n  return ['.jpg','.jpeg','.png','.webp','.mp4'].includes(path.extname(p).toLowerCase());\n}","tryCatchPattern":"try {\n  await cli.post({ media });\n} catch (e) {\n  if (e instanceof ArgumentError && e.message.startsWith('Unsupported media format')) {\n    console.error('Convert to jpg/png/webp/mp4 first. Details:', e.message);\n  } else throw e;\n}","preventionTips":["Convert HEIC/MOV/GIF inputs to jpg/mp4 at ingestion time in pipelines","Check extensions (case-insensitively) before passing media lists","Avoid double extensions like photo.jpg.txt","Remember .gif is not accepted for carousels via this CLI"],"tags":["argument-error","unsupported-format","validation"],"backgroundTag":"unsupported-file-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}