jackwener/OpenCLI · error · ArgumentError
${label} must be PNG, JPEG, WEBP, or GIF: ${ref.value}
Error message
${label} must be PNG, JPEG, WEBP, or GIF: ${ref.value} What it means
Midjourney only accepts PNG, JPEG, WEBP, and GIF uploads. The validator checks the lowercased file extension against the IMAGE_EXTENSIONS set and throws this ArgumentError for anything else — including SVG, HEIC, TIFF, AVIF, BMP, and PDF — before any upload is attempted.
Source
Thrown at clis/midjourney/utils.js:915
return { kind: 'url', value: item };
}
const expanded = item === '~' ? os.homedir() : item.startsWith('~/') ? path.join(os.homedir(), item.slice(2)) : item;
return { kind: 'local', value: path.resolve(expanded) };
});
}
export async function validateLocalReferences(refs, label) {
for (const ref of refs.filter((item) => item.kind === 'local')) {
let stat;
try {
stat = await fs.stat(ref.value);
} catch {
throw new ArgumentError(`${label} file does not exist: ${ref.value}`);
}
if (!stat.isFile() || stat.size <= 0) throw new ArgumentError(`${label} must reference a non-empty file: ${ref.value}`);
if (stat.size > MAX_REFERENCE_BYTES) throw new ArgumentError(`${label} exceeds Midjourney's 10MB upload limit: ${ref.value}`);
const ext = path.extname(ref.value).toLowerCase();
if (!IMAGE_EXTENSIONS.has(ext)) throw new ArgumentError(`${label} must be PNG, JPEG, WEBP, or GIF: ${ref.value}`);
}
return refs;
}
async function visibleImageSources(page) {
const payload = unwrapEvaluateResult(await page.evaluate(() => [...document.querySelectorAll('img[src]')]
.filter((img) => {
const rect = img.getBoundingClientRect();
let card = img.parentElement;
while (card && !String(card.className).includes('group/img')) card = card.parentElement;
return Boolean(card) && rect.width > 24 && rect.height > 24 && /cdn\.midjourney\.com\/u\//.test(img.src);
})
.map((img) => img.src)));
return Array.isArray(payload) ? payload.map(String) : [];
}
export async function openImagePanel(page) {
const markInput = async () => unwrapEvaluateResult(await page.evaluate(() => {View on GitHub (pinned to 49907e53dc)
Solutions
- Convert to a supported format (magick input.heic output.png; ffmpeg -i in.tiff out.png)
- Rename with a correct supported extension if the content is actually PNG/JPEG/WEBP/GIF but mislabeled
- Export from the source tool as PNG/JPEG rather than SVG/PDF
Example fix
// before clis/midjourney --refs ./photo.heic // after magick ./photo.heic ./photo.png clis/midjourney --refs ./photo.png
Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED = new Set(['.png', '.jpeg', '.jpg', '.webp', '.gif']);
const ext = path.extname(p).toLowerCase();
if (!ALLOWED.has(ext)) throw new Error(`${p}: convert to PNG/JPEG/WEBP/GIF first`); Type guard
const hasSupportedImageExt = (p) => ['.png', '.jpeg', '.jpg', '.webp', '.gif'].includes(path.extname(p).toLowerCase());
Try / catch
try {
await validateLocalReferences(refs, 'refs');
} catch (e) {
if (String(e.message).includes('must be PNG, JPEG, WEBP, or GIF')) {
console.error('Convert the file, e.g. magick input.heic output.png');
}
throw e;
} Prevention
- Convert HEIC/TIFF/SVG/AVIF sources to PNG/JPEG before uploading
- Normalize extensions when ingesting files from phones or design tools
- Keep an automated transcode step in pipelines that accept arbitrary images
When it happens
Trigger: A local file with an unsupported extension: .svg, .heic (iPhone photos), .tiff, .avif, .bmp, .pdf, or a file with no extension at all.
Common situations: iOS photos synced as HEIC, Figma exports as SVG/PDF, scanner output as TIFF, modern AVIF saves, or extensionless files downloaded without names.
Related errors
- File not found: ${path}
- File must be a readable text file: ${path}
- 视频文件不存在: ${videoPath}
- Video file not found: ${resolved}
- Receipt file cannot be read: ${receipt}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/b1e5654dc41b17fe.
Report an issue: GitHub.