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
- 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)
- Confirm the URL is publicly accessible or that credentials are passed appropriately
- Re-upload the asset and update the URL
- 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
- Monitor signed-URL expiry (403s) and rotate credentials
- HEAD-check media URLs in CI before shipping configs
- Treat 429 with backoff; treat 403/404 as URL problems, not transient
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
- baml.fetch_as: HTTP request failed: HTTP {} Body: {} at {:?}
- Failed to fetch media: {e:?}
- Failed to fetch media bytes: {e:?}
- Transport error: {0}
- Auth server returned {status}: {body}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/8b275b4b526dde7b.
Report an issue: GitHub.