jackwener/OpenCLI · error · CommandExecutionError

Midjourney media transfer size mismatch: expected ${size}, r

Error message

Midjourney media transfer size mismatch: expected ${size}, received ${buffer.length}

What it means

After concatenating all base64 chunks, the byte length did not match the size the initial payload reported. This indicates a partial or corrupted transfer (some chunks were missed or truncated), so the library refuses to return incomplete media bytes.

Source

Thrown at clis/midjourney/utils.js:590

      const base64 = unwrapEvaluateResult(await page.evaluate((key, start, length) => {
        const bytes = window[key];
        if (!(bytes instanceof Uint8Array)) return null;
        const chunk = bytes.subarray(start, Math.min(bytes.length, start + length));
        let binary = '';
        const binaryChunkSize = 0x8000;
        for (let index = 0; index < chunk.length; index += binaryChunkSize) {
          binary += String.fromCharCode(...chunk.subarray(index, index + binaryChunkSize));
        }
        return btoa(binary);
      }, transferKey, offset, chunkSize));
      if (typeof base64 !== 'string' || !base64) {
        throw new CommandExecutionError(`Midjourney media transfer lost its browser buffer at byte ${offset}`);
      }
      parts.push(Buffer.from(base64, 'base64'));
    }
    const buffer = Buffer.concat(parts);
    if (buffer.length !== size) {
      throw new CommandExecutionError(`Midjourney media transfer size mismatch: expected ${size}, received ${buffer.length}`);
    }
    return { buffer, mime: String(payload.type || '').split(';', 1)[0].toLowerCase() };
  } finally {
    await page.evaluate((key) => {
      delete window[key];
      return true;
    }, transferKey).catch(() => {});
  }
}

function sniffMediaMime(buffer) {
  if (!Buffer.isBuffer(buffer) || buffer.length < 4) return null;
  if (buffer.subarray(0, 8).equals(Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]))) return 'image/png';
  if (buffer[0] === 0xff && buffer[1] === 0xd8 && buffer[2] === 0xff) return 'image/jpeg';
  if (buffer.subarray(0, 4).toString('ascii') === 'RIFF' && buffer.subarray(8, 12).toString('ascii') === 'WEBP') return 'image/webp';
  if (/^GIF8[79]a$/.test(buffer.subarray(0, 6).toString('ascii'))) return 'image/gif';
  if (buffer.subarray(4, 8).toString('ascii') === 'ftyp') return 'video/mp4';
  return null;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry the download; a fresh transfer usually reassembles correctly.
  2. Ensure no concurrent operations run on the same page during the transfer.
  3. Keep the page alive and idle for the full transfer duration.
  4. If reproducible for large files, split transfers or update the library.
Defensive patterns

Strategy: retry

Try / catch

try {
  const { buffer } = await downloadMedia(page, url);
} catch (err) {
  if (/size mismatch/.test(err.message)) {
    await sleep(2000);
    await downloadMedia(page, url); // retry; verify byte length after
  } else throw err;
}

Prevention

When it happens

Trigger: A chunk read silently returned short/incorrect data; the page mutated between reads dropping bytes; mismatch between the declared payload.size and the bytes actually stored in the browser buffer.

Common situations: Unstable long-running browser sessions transferring large videos; page memory pressure; race conditions with concurrent evaluate calls on the same page.

Related errors


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