BoundaryML/baml · error

Failed to fetch media: {} {}, {}

Error message

Failed to fetch media: {} {}, {}

What it means

HTTP-level failure while fetching remote media for an LLM call: the request for the media URL returned a non-success status (or failed to be issued). The message includes the status code and reason so the caller can distinguish 404s, auth failures, and transport errors. It fires in the media-to-base64 conversion path when a media entry is a URL rather than inline base64.

Source

Thrown at engine/baml-runtime/src/internal/llm_client/traits/mod.rs:799

    let response = match fetch_with_proxy(&media_url.url, ctx.proxy_url()).await {
        Ok(response) => response,
        Err(e) => return Err(anyhow::anyhow!("Failed to fetch media: {e:?}")),
    };
    if response.status().is_success() {
        let bytes = match response.bytes().await {
            Ok(bytes) => bytes,
            Err(e) => return Err(anyhow::anyhow!("Failed to fetch media bytes: {e:?}")),
        };
        let base64 = BASE64_STANDARD.encode(&bytes);
        // TODO: infer based on file extension?
        let mime_type = match infer::get(&bytes) {
            Some(t) => t.mime_type(),
            None => "application/octet-stream",
        }
        .to_string();
        Ok((base64, mime_type))
    } else {
        Err(anyhow::anyhow!(
            "Failed to fetch media: {} {}, {}",
            response.status(),
            media_url.url,
            response.text().await.unwrap_or_default(),
        ))
    }
}

/// A naive implementation of the data URL parser, returning the (mime_type, base64)
/// if parsing succeeds. Specifically, we only support specifying a single mime-type (so
/// fields like 'charset' will be ignored) and only base64 data URLs.
///
/// See: https://fetch.spec.whatwg.org/#data-urls
fn as_base64(maybe_base64_url: &str) -> Option<(&str, &str)> {
    if let Some(data_url) = maybe_base64_url.strip_prefix("data:") {
        if let Some((mime_type, base64)) = data_url.split_once(";base64,") {
            return Some((mime_type, base64));
        }

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Check the status code and body in the error message — fix the root cause (usually 403/404 means regenerate the signed URL or fix the path)
  2. Confirm the URL is publicly accessible or that credentials are passed appropriately
  3. Re-upload the asset and update the URL
  4. Fall back to sending base64 data instead of a URL
Defensive patterns

Strategy: fallback

Validate before calling

const res = await fetch(mediaUrl, { method: 'HEAD' });
if (!res.ok) throw new Error(`Media URL returned ${res.status}: ${mediaUrl}`);

Try / catch

try {
  await runBamlFn();
} catch (e) {
  if (/Failed to fetch media: \d+/.test(String(e.message))) {
    const status = parseInt(e.message.match(/Failed to fetch media: (\d+)/)?.[1], 10);
    if (status === 429) await sleep(backoff);
    else console.error('Fix media URL; non-retryable status', status);
  }
  throw e;
}

Prevention

When it happens

Trigger: fetch_with_proxy got a response whose status is not success (404, 403, 500, etc.) while downloading a media URL.

Common situations: Expired or revoked pre-signed S3/GCS URLs (403/404); URL behind authentication; deleted assets; rate limiting (429); wrong host producing 404.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/8b275b4b526dde7b. Report an issue: GitHub.