jackwener/OpenCLI · error · ArgumentError
weixin create-draft cover-image must be JPEG, PNG, GIF, or W
Error message
weixin create-draft cover-image must be JPEG, PNG, GIF, or WebP
What it means
The path is an existing regular file but its extension is not in IMAGE_MIME_TYPES, so the library cannot determine a supported MIME type. WeChat draft cover images must be JPEG, PNG, GIF, or WebP.
Source
Thrown at clis/weixin/create-draft.js:49
}
function resolveCoverImage(rawPath) {
const value = String(rawPath ?? '').trim();
if (!value) throw new ArgumentError('weixin create-draft cover-image cannot be empty');
const absPath = path.resolve(value);
let stat;
try {
stat = fs.statSync(absPath);
} catch {
throw new ArgumentError(`weixin create-draft cover-image does not exist: ${absPath}`);
}
if (!stat.isFile()) {
throw new ArgumentError(`weixin create-draft cover-image is not a file: ${absPath}`);
}
const extension = path.extname(absPath).toLowerCase();
const mimeType = IMAGE_MIME_TYPES.get(extension);
if (!mimeType) {
throw new ArgumentError('weixin create-draft cover-image must be JPEG, PNG, GIF, or WebP');
}
return { absPath, fileName: path.basename(absPath), mimeType };
}
async function navigateToEditor(page) {
await page.goto(WEIXIN_HOME);
await page.wait(3);
const token = await evaluate(page, `(window.location.href.match(/token=(\\d+)/)||[])[1]`);
if (!token) {
throw new AuthRequiredError(WEIXIN_DOMAIN, 'Please log in to the WeChat Official Account platform and retry.');
}
await page.goto(`https://mp.weixin.qq.com/cgi-bin/appmsg?t=media/appmsg_edit_v2&action=edit&isNew=1&type=77&token=${token}&lang=zh_CN`);
await page.wait(4);
const hasTitle = await evaluate(page, '!!document.querySelector("textarea#title")');
if (hasTitle !== true) {
throw new CommandExecutionError('WeChat article editor did not load. The session may have expired.');
}
}View on GitHub (pinned to 49907e53dc)
Solutions
- Convert the image to JPEG, PNG, GIF, or WebP (e.g. with sharp/ImageMagick).
- Rename the file so it has a supported extension if it actually is one of those formats.
- Check the IMAGE_MIME_TYPES map if you maintain the CLI and add needed types deliberately.
Example fix
// before coverImage: 'photo.heic' // after // magick photo.heic photo.jpg coverImage: 'photo.jpg'
Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED = ['.jpg','.jpeg','.png','.gif','.webp'];
const ext = path.extname(coverImage).toLowerCase();
if (!SUPPORTED.includes(ext)) throw new Error(`unsupported cover format: ${ext}`); Type guard
function isSupportedImage(p) {
return ['.jpg','.jpeg','.png','.gif','.webp'].includes(path.extname(p).toLowerCase());
} Try / catch
try {
await createDraft({ coverImage });
} catch (err) {
if (err instanceof ArgumentError && err.message.includes('JPEG, PNG, GIF')) {
console.error('Convert the image to JPEG/PNG/GIF/WebP first');
} else throw err;
} Prevention
- Normalize/convert images to supported formats in a pre-step
- Strip HEIC/BMP/TIFF inputs at ingestion
- Keep extensions lowercase and consistent
- Optionally verify MIME via magic bytes, not just extension
When it happens
Trigger: Passing a cover image with an unsupported extension (.bmp, .tiff, .avif, .heic) or an odd/uppercase-less mismatch such as .jpeg-less variants the map lacks; also a non-image file renamed to .png is caught only if the extension is unknown.
Common situations: Modern camera HEIC files; screenshots saved as BMP/TIFF; files with no extension; case-sensitive extension lookup on '.PNG' if the map is lowercase-only and extname case differs (here extname is lowercased, so truly exotic extensions only).
Related errors
- weixin create-draft cover-image cannot be empty
- Unsupported image format "${ext}". Supported: jpg, png, gif,
- archive search sort must be one of ${SORT_OPTIONS.join(', ')
- archive search mediatype must be one of ${MEDIATYPES.join(',
- archive search limit must be a positive integer
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/a999dda89c747d70.
Report an issue: GitHub.