jackwener/OpenCLI · error · CommandExecutionError

Midjourney media download failed: HTTP ${payload?.status ??

Error message

Midjourney media download failed: HTTP ${payload?.status ?? 0} from ${url}

What it means

The in-page fetch completed but the payload reported ok=false (or no payload), meaning the CDN returned a non-2xx HTTP status. The error surfaces the actual HTTP status code and the URL so you can see why the media could not be downloaded.

Source

Thrown at clis/midjourney/utils.js:557

        // CDN is public but Cloudflare-protected. Browser-origin fetch succeeds
        // with default same-origin credential mode; forcing cross-origin cookies
        // turns it into a credentialed CORS request and Midjourney rejects it.
        const response = await fetch(mediaUrl);
        if (!response.ok) return { ok: false, status: response.status, type: response.headers.get('content-type') || '' };
        const bytes = new Uint8Array(await response.arrayBuffer());
        window[key] = bytes;
        return {
          ok: true,
          status: response.status,
          type: response.headers.get('content-type') || '',
          size: bytes.length,
        };
      }, url, transferKey));
    } catch (error) {
      throw new CommandExecutionError(`Midjourney browser-context media fetch failed: ${errorMessage(error)}`);
    }
    if (!payload || typeof payload !== 'object' || !payload.ok) {
      throw new CommandExecutionError(`Midjourney media download failed: HTTP ${payload?.status ?? 0} from ${url}`);
    }
    if (!String(payload.type || '').startsWith(expectedMimePrefix)) {
      throw new CommandExecutionError(`Midjourney media download returned unexpected content type "${payload.type || 'unknown'}"`);
    }
    const size = Number(payload.size);
    if (!Number.isInteger(size) || size <= 0) {
      throw new CommandExecutionError(`Midjourney media download returned an empty file from ${url}`);
    }

    // Returning a complete base64 file in one Browser Bridge response can
    // exceed the daemon message limit. Pull it out in bounded chunks instead.
    const parts = [];
    const chunkSize = 96 * 1024;
    for (let offset = 0; offset < size; offset += chunkSize) {
      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));

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-resolve a fresh media URL for the job (signed URLs expire) and retry.
  2. Check the HTTP status in the message: 403/404 means URL expired or wrong; 429 means back off and retry later; 5xx means retry after a delay.
  3. Verify the jobId is correct.
  4. Reduce download concurrency to avoid CDN rate limits.
Defensive patterns

Strategy: retry

Validate before calling

const res = await fetch(url, { method: 'HEAD' });
if (!res.ok) throw new Error('Media URL not ready: HTTP ' + res.status + ' for ' + url);

Try / catch

try {
  await downloadMedia(page, url);
} catch (err) {
  const m = err.message.match(/HTTP (\d+)/);
  if (m && ['429','500','502','503'].includes(m[1])) {
    await sleep(backoff);
    await downloadMedia(page, url); // retry transient statuses
  } else if (m && ['403','404'].includes(m[1])) {
    await downloadMedia(page, await resolveFreshUrl(jobId)); // expired URL
  } else throw err;
}

Prevention

When it happens

Trigger: The media URL returns 403 (expired signed CDN link), 404 (media deleted or wrong URL), 429 (rate limited), or 5xx (CDN error); payload came back null/not an object because the page returned something unexpected.

Common situations: Re-running downloads hours after job completion when signed URLs expired; mistyped or stale jobIds producing wrong URLs; Midjourney CDN rate limiting many parallel downloads.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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