{"record":{"id":"b5a49113bd8e164e","repo":"jackwener/OpenCLI","slug":"unsupported-image-format-ext-supported-jpg-b5a491","errorCode":null,"errorMessage":"Unsupported image format \"${ext}\". Supported: jpg, jpeg, png, webp","messagePattern":"Unsupported image format \"(.+?)\"\\. Supported: jpg, jpeg, png, webp","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/xianyu/publish.js","lineNumber":68,"sourceCode":"    const condition = requireText(value, 'condition');\n    if (!CONDITION_CHOICES.includes(condition)) {\n        throw new ArgumentError(`xianyu publish condition must be one of: ${CONDITION_CHOICES.join(', ')}`);\n    }\n    return condition;\n}\n\nfunction validateImagePaths(raw) {\n    if (!raw) return [];\n    const paths = String(raw).split(',').map((item) => item.trim()).filter(Boolean);\n    if (paths.length === 0) return [];\n    if (paths.length > MAX_IMAGES) {\n        throw new ArgumentError(`xianyu publish images supports at most ${MAX_IMAGES} files`);\n    }\n    return paths.map((item) => {\n        const absPath = path.resolve(item);\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, webp`);\n        }\n        const stat = fs.statSync(absPath, { throwIfNoEntry: false });\n        if (!stat || !stat.isFile()) {\n            throw new ArgumentError(`Not a valid image file: ${absPath}`);\n        }\n        return absPath;\n    });\n}\n\nfunction normalizePublishArgs(kwargs) {\n    const price = parsePositivePrice(kwargs.price, 'price');\n    if (price == null) {\n        throw new ArgumentError('xianyu publish price cannot be empty');\n    }\n    const normalized = {};\n    normalized.title = requireText(kwargs.title, 'title');\n    normalized.description = requireText(kwargs.description, 'description');\n    normalized.price = price;","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xianyu/publish.js#L50-L86","documentation":"validateImagePaths throws ArgumentError when an image path's lowercased extension is not in SUPPORTED_IMAGE_EXTENSIONS (.jpg, .jpeg, .png, .webp). The check runs on path.extname before any filesystem access, so extension — not file content — is what fails.","triggerScenarios":"Passing images like 'photo.HEIC' (iPhone), 'cat.gif', 'screenshot.bmp', or extension-less files; any ext not in {'.jpg','.jpeg','.png','.webp'} throws.","commonSituations":"iOS HEIC photos not converted before upload, GIFs/BMPs from screenshots, newer formats like .avif, or paths whose extensions were stripped after copy/move.","solutions":["Convert the image to jpg/png/webp (e.g. sharp, ffmpeg, or macOS 'sips -s format jpeg')","Do not merely rename — re-encode, since content must match the extension","Filter the image list against the supported extension set before calling publish"],"exampleFix":"// before\nawait publish({ images: 'IMG_0001.HEIC' });\n// after\n// $ sips -s format jpeg IMG_0001.HEIC --out IMG_0001.jpg\nawait publish({ images: 'IMG_0001.jpg' });","handlingStrategy":"validation","validationCode":"const SUPPORTED = new Set(['.jpg', '.jpeg', '.png', '.webp']);\nfor (const p of images.split(',')) {\n  const ext = path.extname(p.trim()).toLowerCase();\n  if (!SUPPORTED.has(ext)) throw new Error(`Convert ${p}: unsupported format ${ext}`);\n}","typeGuard":"function isSupportedImage(p) {\n  return ['.jpg', '.jpeg', '.png', '.webp'].includes(path.extname(p).toLowerCase());\n}","tryCatchPattern":"try {\n  await publish({ images });\n} catch (e) {\n  if (e instanceof ArgumentError && /Unsupported image format/.test(e.message)) {\n    console.error('Convert unsupported files to jpg/png/webp before publishing');\n  } else throw e;\n}","preventionTips":["Convert HEIC/AVIF/GIF/BMP to jpg or png during ingestion","Check extensions early in your pipeline, not at publish time","Re-encode rather than renaming only"],"tags":["validation","argument-error","images","file-format"],"backgroundTag":"unsupported-file-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}