jackwener/OpenCLI · error · CommandExecutionError
Too many images: ${paths.length} (max ${MAX_IMAGES})
Error message
Too many images: ${paths.length} (max ${MAX_IMAGES}) What it means
CommandExecutionError thrown by validateImagePaths when a comma-separated image path list contains more than MAX_IMAGES (4) entries. X.com allows at most 4 images per post, so the CLI enforces this limit before opening the composer to avoid a guaranteed upload failure. Raised in validateImagePaths, called via absPaths before any browser interaction.
Source
Thrown at clis/twitter/post.js:22
import { CommandExecutionError, TimeoutError } from '@jackwener/opencli/errors';
import { unwrapBrowserResult } from './shared.js';
import { isRecoverableFileInputError } from './utils.js';
const MAX_IMAGES = 4;
const UPLOAD_POLL_MS = 500;
const UPLOAD_TIMEOUT_MS = 30_000;
const COMPOSER_POLL_MS = 250;
const COMPOSER_TIMEOUT_MS = 10_000;
const SUBMIT_POLL_MS = 500;
const SUBMIT_TIMEOUT_MS = 15_000;
const COMPOSE_URL = 'https://x.com/compose/post';
const FILE_INPUT_SELECTOR = 'input[type="file"][data-testid="fileInput"]';
const SUPPORTED_EXTENSIONS = new Set(['.jpg', '.jpeg', '.png', '.gif', '.webp']);
function validateImagePaths(raw) {
const paths = raw.split(',').map(s => s.trim()).filter(Boolean);
if (paths.length > MAX_IMAGES) {
throw new CommandExecutionError(`Too many images: ${paths.length} (max ${MAX_IMAGES})`);
}
return paths.map(p => {
const absPath = path.resolve(p);
const ext = path.extname(absPath).toLowerCase();
if (!SUPPORTED_EXTENSIONS.has(ext)) {
throw new CommandExecutionError(`Unsupported image format "${ext}". Supported: jpg, png, gif, webp`);
}
const stat = fs.statSync(absPath, { throwIfNoEntry: false });
if (!stat || !stat.isFile()) {
throw new CommandExecutionError(`Not a valid file: ${absPath}`);
}
return absPath;
});
}
function isUnsupportedInsertTextError(err) {
const msg = err instanceof Error ? err.message : String(err);
const lower = msg.toLowerCase();View on GitHub (pinned to 49907e53dc)
Solutions
- Reduce the comma-separated list to at most 4 image paths.
- Split posts into multiple tweets if you need more than 4 images (each with its own set).
- In scripts, slice the file list to 4 before invoking: files.slice(0, 4).join(',').
- Consider a video post instead — X's video path has different (larger) limits.
Example fix
// before
const images = allFiles.join(',');
await post({ text, images }); // may exceed 4
// after
const images = allFiles.slice(0, 4).join(',');
if (allFiles.length > 4) console.warn('Posting only first 4 images; Twitter allows max 4 per post');
await post({ text, images }); Defensive patterns
Strategy: validation
Validate before calling
const paths = rawImages.split(',').map(s => s.trim()).filter(Boolean);
if (paths.length > 4) throw new Error(`Max 4 images per post, got ${paths.length}`); Type guard
function isWithinImageLimit(paths, max = 4) {
return Array.isArray(paths) && paths.length <= max;
} Try / catch
try {
await run(['twitter', 'post', '--images', rawImages]);
} catch (err) {
if (err.message.startsWith('Too many images')) {
const first4 = rawImages.split(',').map(s => s.trim()).filter(Boolean).slice(0, 4).join(',');
await run(['twitter', 'post', '--images', first4]);
} else throw err;
} Prevention
- Remember Twitter's hard limit of 4 images per post
- Slice or chunk file lists in scripts before joining into a comma string
- Watch for glob/directory expansion silently producing extra paths
When it happens
Trigger: Calling the twitter post command with an --images/-style comma-joined string containing 5+ paths, e.g. 'a.jpg,b.png,c.jpg,d.png,e.jpg' — after trim/filter the array length exceeds 4.
Common situations: Globbing directories into a comma list and exceeding the limit; scripts joining all files in a folder; users unaware of Twitter's 4-image cap; trailing-comma strings that leave extra entries after filtering.
Related errors
- Unsupported image format "${ext}". Supported: jpg, png, gif,
- 标题不能超过 30 字
- 正文不能超过 1000 字
- ${name} must be <= ${max}
- pubmed ${label} must be <= ${maxValue}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/780429613bfebf99.
Report an issue: GitHub.