jackwener/OpenCLI · error · ArgumentError
Image too large: ${(stat.size / 1024 / 1024).toFixed(1)} MB
Error message
Image too large: ${(stat.size / 1024 / 1024).toFixed(1)} MB (max ${MAX_IMAGE_SIZE_BYTES / 1024 / 1024} MB) What it means
resolveImagePath enforces MAX_IMAGE_SIZE_BYTES = 20MB (a safety net above Twitter's own ~5MB image / 15MB GIF limits). If fs.statSync reports a larger file it throws ArgumentError with the size in MB. Oversized media would fail later at X's upload endpoint, so it is rejected up front.
Source
Thrown at clis/twitter/utils.js:51
/**
* Validate a single image path. Throws {@link ArgumentError} on bad input
* (typed input failure surfaces before any browser interaction).
*
* @param {string} imagePath - Local filesystem path, may be relative.
* @returns {string} Absolute resolved path.
*/
export function resolveImagePath(imagePath) {
const absPath = path.resolve(imagePath);
if (!fs.existsSync(absPath)) {
throw new ArgumentError(`Image file not found: ${absPath}`);
}
const ext = path.extname(absPath).toLowerCase();
if (!SUPPORTED_IMAGE_EXTENSIONS.has(ext)) {
throw new ArgumentError(`Unsupported image format "${ext}". Supported: jpg, jpeg, png, gif, webp`);
}
const stat = fs.statSync(absPath);
if (stat.size > MAX_IMAGE_SIZE_BYTES) {
throw new ArgumentError(`Image too large: ${(stat.size / 1024 / 1024).toFixed(1)} MB (max ${MAX_IMAGE_SIZE_BYTES / 1024 / 1024} MB)`);
}
return absPath;
}
/**
* Resolve the file extension to use when persisting a remote image: prefer
* Content-Type, fall back to URL pathname.
*/
export function resolveImageExtension(url, contentType) {
const normalizedContentType = (contentType || '').split(';')[0].trim().toLowerCase();
if (normalizedContentType && CONTENT_TYPE_TO_EXTENSION[normalizedContentType]) {
return CONTENT_TYPE_TO_EXTENSION[normalizedContentType];
}
try {
const pathname = new URL(url).pathname;
const ext = path.extname(pathname).toLowerCase();
if (SUPPORTED_IMAGE_EXTENSIONS.has(ext))
return ext;View on GitHub (pinned to 49907e53dc)
Solutions
- Compress or resize the image before uploading, e.g. `magick input.png -resize 1600x -quality 85 output.jpg`.
- Convert PNG screenshots to JPEG to shrink them dramatically.
- For GIFs, reduce frames/dimensions (`gifsicle --resize-width 800 --colors 128`) or convert to MP4 if the post allows video.
- If you legitimately need >20MB media, that cap is a library constant (MAX_IMAGE_SIZE_BYTES in clis/twitter/utils.js:21) — raise it only knowing X's own limits will still apply.
Example fix
// before
await postWithImage('fullpage.png'); // 34 MB
// after
execSync('magick fullpage.png -resize 2000x -quality 85 fullpage.jpg'); // ~2 MB
await postWithImage('fullpage.jpg'); Defensive patterns
Strategy: validation
Validate before calling
const MAX = 20 * 1024 * 1024;
const stat = fs.statSync(imagePath);
if (stat.size > MAX) {
throw new Error(`${imagePath} is ${(stat.size / 1048576).toFixed(1)} MB; compress below 20 MB first`);
} Try / catch
try {
await postWithImage(imagePath);
} catch (err) {
if (err instanceof ArgumentError && /Image too large/.test(err.message)) {
const small = await compressImage(imagePath); // magick -resize/-quality
return postWithImage(small);
}
throw err;
} Prevention
- Check file size before upload: keep images < ~5MB and GIFs < 15MB to also satisfy X limits.
- Convert large PNG screenshots to JPEG with quality ~85.
- Downscale to at most ~1600-2000px on the long edge for typical posts.
When it happens
Trigger: Passing a local image larger than 20MB: high-resolution PNG screenshots, long GIFs, uncompressed camera RAW-renamed files, or any stat.size exceeding 20*1024*1024 bytes.
Common situations: 4K/full-page screenshots saved as PNG (often >20MB); long animated GIFs; video files accidentally renamed to .gif; image downloads that were never compressed.
Related errors
- Image too large: ${(contentLength / 1024 / 1024).toFixed(1)}
- Unknown 12306 station telecode "${trimmed}"
- Unknown 12306 station "${trimmed}"
- date must be YYYY-MM-DD, got "${value}"
- date "${value}" is not a real calendar date
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/4f0a552fa9a633f0.
Report an issue: GitHub.