jackwener/OpenCLI · error · CliError

INVALID_TYPE

INVALID_TYPE

Error message

INVALID_TYPE

What it means

INVALID_TYPE is thrown by the yollomi upload command when the file's extension is not present in the MIME_MAP lookup table. The library only supports a fixed set of media types (jpg, png, gif, webp, mp4, mov) because those are what the yollomi.com upload endpoint and its browser-bridge injection can handle. It is a fail-fast guard thrown before any upload is attempted.

Source

Thrown at clis/yollomi/upload.js:37

cli({
    site: 'yollomi',
    name: 'upload',
    access: 'write',
    description: 'Upload an image or video to Yollomi (returns URL for other commands)',
    domain: YOLLOMI_DOMAIN,
    strategy: Strategy.COOKIE,
    args: [
        { name: 'file', positional: true, required: true, help: 'Local file path to upload' },
    ],
    columns: ['status', 'file', 'size', 'url'],
    func: async (page, kwargs) => {
        const filePath = path.resolve(kwargs.file);
        if (!fs.existsSync(filePath))
            throw new CliError('FILE_NOT_FOUND', `File not found: ${filePath}`, 'Provide a valid file path');
        const ext = path.extname(filePath).toLowerCase();
        const mime = MIME_MAP[ext];
        if (!mime)
            throw new CliError('INVALID_TYPE', `Unsupported file type: ${ext}`, 'Supported: jpg, png, gif, webp, mp4, mov');
        const data = fs.readFileSync(filePath);
        // Note: base64 encoding inflates size ~33%. Video cap is conservative to avoid
        // OOM when the base64 string is injected into the browser JS engine via page.evaluate().
        const maxSize = mime.startsWith('video/') ? 20 * 1024 * 1024 : 10 * 1024 * 1024;
        if (data.length > maxSize)
            throw new CliError('FILE_TOO_LARGE', `File too large: ${fmtBytes(data.length)}`, `Max ${mime.startsWith('video/') ? '20MB' : '10MB'} (upload larger videos from a URL)`);
        const b64 = data.toString('base64');
        const fileName = path.basename(filePath);
        log.status(`Uploading ${fileName} (${fmtBytes(data.length)})...`);
        await ensureOnYollomi(page);
        const result = await page.evaluate(`
      (async () => {
        try {
          const raw = atob(${JSON.stringify(b64)});
          const arr = new Uint8Array(raw.length);
          for (let i = 0; i < raw.length; i++) arr[i] = raw.charCodeAt(i);
          const file = new File([arr], ${JSON.stringify(fileName)}, { type: ${JSON.stringify(mime)} });
          const fd = new FormData();

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Convert the file to a supported format (jpg/png/gif/webp for images, mp4/mov for video) before uploading
  2. Rename the file to use a supported extension if it is actually a supported format misnamed (e.g. a jpg saved as .jfif is not mapped — convert, don't rename blindly)
  3. Check the extension with `ls`/`file` to confirm the actual format, since path.extname trusts the name not the content
  4. Upload via URL instead if the format cannot be converted

Example fix

// before
yollomi upload ./notes.pdf
// throws INVALID_TYPE
// after
convert notes.pdf notes.png   # e.g. with ImageMagick
yollomi upload ./notes.png
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = ['.jpg','.png','.gif','.webp','.mp4','.mov'];
if (!SUPPORTED.includes(path.extname(file).toLowerCase())) {
  throw new Error(`Convert ${file}: extension ${path.extname(file)} not supported`);
}

Type guard

function isSupportedMedia(file) {
  return ['.jpg','.png','.gif','.webp','.mp4','.mov']
    .includes(path.extname(file).toLowerCase());
}

Try / catch

try {
  await upload(file);
} catch (e) {
  if (e.code === 'INVALID_TYPE') console.error(`Unsupported type: convert ${file} to jpg/png/gif/webp/mp4/mov`);
  else throw e;
}

Prevention

When it happens

Trigger: Running the upload command with a file whose extension (path.extname, lowercased) is absent from MIME_MAP, e.g. .pdf, .txt, .avi, .mkv, .heic, .jfif, or a file with no extension at all (mime = undefined).

Common situations: Uploading screenshots saved as .bmp or .tiff, camera footage as .mkv/.avi, HEIC iPhone photos, or files stripped of extensions during download; also typos in extension case are handled, but unusual variants like .jpeg? no — .jpeg maps, but .jfif does not.

Related errors


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