jackwener/OpenCLI · error · ArgumentError

Unsupported image format "${ext}". Supported: jpg, png, gif,

Error message

Unsupported image format "${ext}". Supported: jpg, png, gif, webp

What it means

ArgumentError from validateImagePaths: the image file exists but its extension (lowercased) is not a key in SUPPORTED_EXTENSIONS (jpg, png, gif, webp). XHS's uploader only accepts these formats, so the CLI rejects other files up front.

Source

Thrown at clis/xiaohongshu/publish.js:132

        && typeof value.session === 'string'
        && Object.prototype.hasOwnProperty.call(value, 'data')
    ) {
        return value.data;
    }
    return value;
}
/**
 * Validate image paths: check existence and extension.
 * Returns resolved absolute paths.
 */
function validateImagePaths(filePaths) {
    return filePaths.map((filePath) => {
        const absPath = path.resolve(filePath);
        if (!fs.existsSync(absPath))
            throw new ArgumentError(`Image file not found: ${absPath}`);
        const ext = path.extname(absPath).toLowerCase();
        if (!SUPPORTED_EXTENSIONS[ext]) {
            throw new ArgumentError(`Unsupported image format "${ext}". Supported: jpg, png, gif, webp`);
        }
        return absPath;
    });
}
/** CSS selector for image-accepting file inputs. */
const IMAGE_INPUT_SELECTOR = 'input[type="file"][accept*="image"],'
    + 'input[type="file"][accept*=".jpg"],'
    + 'input[type="file"][accept*=".jpeg"],'
    + 'input[type="file"][accept*=".png"],'
    + 'input[type="file"][accept*=".gif"],'
    + 'input[type="file"][accept*=".webp"]';
/**
 * Upload images via CDP DOM.setFileInputFiles — Chrome reads files directly
 * from the local filesystem, avoiding base64 payload size limits.
 *
 * Falls back to the legacy base64 DataTransfer approach if the extension
 * does not support set-file-input (e.g. older extension version).
 */

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Convert the image to jpg/png/webp (e.g. `sips -s format jpeg in.heic --out out.jpg` or ImageMagick `convert`).
  2. Rename `.jpeg` to `.jpg` if that is the only issue — or convert if .jpeg is not in the supported map.
  3. Add the correct extension if the file was downloaded without one.
  4. Check the extension actually matches the file content (file command) to avoid upload failure later.

Example fix

// before
await xhs.publish({ images: ['photo.heic'] });
// after
// convert first: magick photo.heic photo.jpg
await xhs.publish({ images: ['photo.jpg'] });
Defensive patterns

Strategy: validation

Validate before calling

const OK = new Set(['.jpg', '.png', '.gif', '.webp']);
for (const p of images) {
  const ext = require('path').extname(p).toLowerCase();
  if (!OK.has(ext)) throw new Error(`Convert ${p} (${ext}) to jpg/png/gif/webp first`);
}

Type guard

function isSupportedImage(p) {
  return ['.jpg', '.png', '.gif', '.webp']
    .includes(require('path').extname(String(p)).toLowerCase());
}

Try / catch

try {
  await xhs.publish({ images });
} catch (err) {
  if (err.message.startsWith('Unsupported image format')) {
    console.error('Convert the file, e.g. magick in.heic out.jpg');
  } else throw err;
}

Prevention

When it happens

Trigger: Passing .jpeg, .bmp, .tiff, .heic, .avif, or extensionless files to publish; files downloaded without an extension; uppercase extensions are fine (extname is lowercased), but exotic ones are not.

Common situations: iPhone HEIC photos, .jpeg naming, screenshots saved as .tiff on macOS, or images with missing extensions from downloads.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/3bdf2bc947b7f6ef. Report an issue: GitHub.