jackwener/OpenCLI · error · CommandExecutionError
Midjourney raw video returned invalid MP4 bytes from ${url}
Error message
Midjourney raw video returned invalid MP4 bytes from ${url} What it means
Thrown by the raw-video download path when the bytes fetched from the Midjourney CDN via the browser page do not sniff as video/mp4. The library validates the magic bytes of every downloaded raw video before writing it to disk, guarding against HTML error pages, expired-CDN responses, or truncated downloads being cached as valid MP4s. It indicates the CDN did not serve a genuine MP4 for that media URL.
Source
Thrown at clis/midjourney/utils.js:720
try {
await fs.writeFile(tempPath, buffer);
await fs.rename(tempPath, filePath);
} catch (error) {
await fs.unlink(tempPath).catch(() => {});
throw new CommandExecutionError(`Could not write Midjourney media ${filePath}: ${errorMessage(error)}`);
}
}
export async function downloadRawVideo(page, jobId, index, outputDir, force = false) {
await fs.mkdir(outputDir, { recursive: true });
const url = rawVideoUrl(jobId, index);
const filePath = path.join(outputDir, `${jobId}_${index + 1}_raw.mp4`);
const existing = await existingMedia(filePath, force, 'video/mp4');
if (existing) return { index, kind: 'video-raw', filePath, bytes: existing.size, url, mime: 'video/mp4', cached: true };
const media = await fetchMediaThroughPage(page, url, 'video/');
const actualMime = sniffMediaMime(media.buffer);
if (actualMime !== 'video/mp4') {
throw new CommandExecutionError(`Midjourney raw video returned invalid MP4 bytes from ${url}`);
}
if (media.mime !== actualMime) {
log.warn(`Midjourney CDN reported ${media.mime || 'unknown'} for ${url}; detected ${actualMime} from file bytes`);
}
await writeMediaBuffer(filePath, media.buffer);
return { index, kind: 'video-raw', filePath, bytes: media.buffer.length, url, mime: actualMime, cached: false };
}
export async function downloadRenderedVideo(page, jobId, index, kind, outputDir, force = false) {
const config = kind === 'video-social'
? { label: 'Download for Social', extension: '.mp4', mime: 'video/mp4' }
: kind === 'gif'
? { label: 'Download as GIF', extension: '.gif', mime: 'image/gif' }
: null;
if (!config) throw new ArgumentError('Rendered video kind must be video-social or gif');
await fs.mkdir(outputDir, { recursive: true });
const filePath = path.join(outputDir, `${jobId}_${index + 1}_${kind.replace('video-', '')}${config.extension}`);
const existing = await existingMedia(filePath, force, config.mime);View on GitHub (pinned to 49907e53dc)
Solutions
- Re-run the command with a fresh authenticated browser session so the CDN serves the real video instead of an error page
- Check what the URL actually returns (curl -I) — if text/html, the CDN link has expired; re-open the job page to get a fresh URL
- Log or inspect the sniffed actualMime to identify the real content type and, if it is a supported-but-unlabeled variant, extend sniffMediaMime
- Disable interfering proxies/MITM tools and retry
- Delete any partially-written output file and retry with force to bypass the cache
Example fix
// before
if (actualMime !== 'video/mp4') {
throw new CommandExecutionError(`Midjourney raw video returned invalid MP4 bytes from ${url}`);
}
// after
if (actualMime !== 'video/mp4') {
log.warn(`Retrying fetch for ${url}; got ${actualMime}`);
const retry = await fetchMediaThroughPage(page, url, 'video/');
if (sniffMediaMime(retry.buffer) !== 'video/mp4') {
throw new CommandExecutionError(`Midjourney raw video returned invalid MP4 bytes from ${url} (got ${actualMime})`);
}
media.buffer = retry.buffer;
} Defensive patterns
Strategy: validation
Validate before calling
const res = await fetch(url, { headers: { cookie: sessionCookie } });
const head = Buffer.from(await res.arrayBuffer()).subarray(0, 16);
const isMp4 = head.subarray(4, 8).toString('binary') === 'ftyp';
if (!isMp4) throw new Error(`URL ${url} is not serving MP4 (content-type ${res.headers.get('content-type')})`); Type guard
function isMp4Buffer(buf) {
return buf.length > 11 && buf.subarray(4, 8).toString('binary') === 'ftyp';
} Try / catch
try {
const result = await downloadRawVideo(page, url, jobId, index, outputDir);
} catch (err) {
if (err.message.includes('invalid MP4 bytes')) {
await refreshSession(page);
return downloadRawVideo(page, url, jobId, index, outputDir, true);
}
throw err;
} Prevention
- Keep the browser session authenticated so CDN URLs resolve to media, not error pages
- Use fresh job page URLs rather than long-lived CDN links that may have expired
- Pre-validate media URLs with a HEAD request for content-type video/ before download
- Clear stale cached output files with --force after session or CDN changes
When it happens
Trigger: downloadRawVideo fetches a raw video URL with fetchMediaThroughPage and sniffMediaMime(buffer) returns something other than 'video/mp4' (e.g. 'text/html', 'image/webp', or 'unknown').
Common situations: Expired Midjourney CDN links returning an HTML error page; session cookies missing so the CDN returns a login/redirect page; the CDN serving WebM or fragmented MP4 variants whose magic bytes the sniffer does not recognize; a proxy or corporate TLS interceptor replacing the response body.
Related errors
- Midjourney did not expose a Describe action for the uploaded
- Midjourney Describe
- Midjourney Imagine composer was not found.
- composer fill was not verified
- Could not submit the Midjourney prompt: ${error instanceof E
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/52ce88df3671a2bd.
Report an issue: GitHub.