jackwener/OpenCLI · error · CliError

FILE_TOO_LARGE

FILE_TOO_LARGE

Error message

FILE_TOO_LARGE

What it means

FILE_TOO_LARGE is thrown when the file read into memory exceeds the size cap for its MIME class: 20MB for video, 10MB for everything else. The caps exist because the file is base64-encoded (~33% larger) and injected into the browser JS engine via page.evaluate(), so oversized payloads risk OOM crashes of the Chrome tab.

Source

Thrown at clis/yollomi/upload.js:43

    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();
          fd.append('file', file);
          const res = await fetch('/api/upload', { method: 'POST', body: fd, credentials: 'include' });
          const json = await res.json();
          return { ok: res.ok, status: res.status, data: json };
        } catch (err) {
          return { ok: false, status: 0, data: { error: err.message } };

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Compress or downscale the file (e.g. export the image as jpg quality ~80, or re-encode video at a lower bitrate)
  2. For videos over 20MB, use the documented alternative: upload from a URL instead of embedding the file
  3. Check the size first with `ls -lh` or `stat -c %s` and split/trim media (e.g. trim video length)
  4. If the file is a video, remember the cap is 20MB; images cap at 10MB — verify you are not misclassifying

Example fix

// before
yollomi upload ./screen-recording.mov  // 40MB
// throws FILE_TOO_LARGE
// after
ffmpeg -i screen-recording.mov -b:v 1M -fs 18M screen-recording-small.mov
yollomi upload ./screen-recording-small.mov
Defensive patterns

Strategy: validation

Validate before calling

const stat = fs.statSync(file);
const isVideo = ['.mp4','.mov'].includes(path.extname(file).toLowerCase());
const max = isVideo ? 20*1024*1024 : 10*1024*1024;
if (stat.size > max) throw new Error(`${file} is ${stat.size} bytes; max ${max}`);

Type guard

function withinSizeLimit(file) {
  const video = ['.mp4','.mov'].includes(path.extname(file).toLowerCase());
  const max = video ? 20*1024*1024 : 10*1024*1024;
  return fs.existsSync(file) && fs.statSync(file).size <= max;
}

Try / catch

try {
  await upload(file);
} catch (e) {
  if (e.code === 'FILE_TOO_LARGE') console.error('Compress or upload from a URL instead');
  else throw e;
}

Prevention

When it happens

Trigger: Calling the upload command with a file whose byte length (fs.readFileSync result) exceeds 10MB for images or 20MB for videos — e.g. a 12MB png screenshot or a 25MB mp4 clip.

Common situations: Uploading raw camera 4K video clips, high-resolution PNG screenshots, uncompressed scans, or GIF exports from animation tools; also hitting the cap after the file passed the type check because size was never considered.

Related errors


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