BoundaryML/baml · error

Failed to fetch media

Error message

Failed to fetch media: {e:?}

What it means

to_base64_with_inferred_mime_type failed at the network layer while downloading the media URL (fetch_with_proxy returned Err). BAML wraps the underlying reqwest error in this message rather than silently sending empty content.

Solutions

  1. Verify the URL is reachable (curl it from the same host)
  2. Check for expired pre-signed URLs and regenerate them
  3. If a proxy is configured, verify BAML's proxy setting is correct and the proxy is up
  4. Encode the media as a base64 data URL to skip fetching entirely
Defensive patterns

Strategy: retry

Validate before calling

const reachable = await fetch(url, { method: 'HEAD' }).then(r => r.ok).catch(() => false);
if (!reachable) throw new Error(`Media URL unreachable: ${url}`);

Try / catch

try {
  await runBamlFn();
} catch (e) {
  if (/Failed to fetch media:/.test(String(e.message)) && attempts < 3) {
    await sleep(2 ** attempts * 500);
    return runBamlFn(attempts + 1);
  }
  throw e;
}

Prevention

When it happens

Trigger: The media URL is unreachable: DNS failure, connection refused/reset, TLS error, or a configured proxy is down, and the URL is not a base64 data URL.

Common situations: Private/internal URLs not reachable from the runtime host; typos in the domain; expired signed URLs (S3/GCS); no internet access or corporate proxy misconfiguration.

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 BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/07adb62253aa5825. Report an issue: GitHub.

Appendix: source

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

            Ok(BamlMedia::base64(
                part.media_type,
                media_b64.base64.clone(),
                mime_type,
            ))
        }
    }
}

async fn to_base64_with_inferred_mime_type(
    ctx: &RuntimeContext,
    media_url: &MediaUrl,
) -> Result<(String, String)> {
    if let Some((mime_type, base64)) = as_base64(media_url.url.as_str()) {
        return Ok((base64.to_string(), mime_type.to_string()));
    }
    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(),

View on GitHub (pinned to bd85ce9dee)