BoundaryML/baml · error
AWS Bedrock requires s3:// URIs, but got: {}
Error message
AWS Bedrock requires s3:// URIs, but got: {} What it means
media_to_content_block_json validates that any URL-referenced media sent to AWS Bedrock modular requests uses an s3:// URI, because the Converse API S3Location source only accepts S3 URIs. If the URL scheme is anything else (https://, http://, file://, typoed s3:/), the client bails with this error before making the API call.
Source
Thrown at engine/baml-runtime/src/internal/llm_client/primitive/aws/aws_client.rs:89
fn strip_mime_prefix(mime: &str) -> &str {
mime.split_once('/').map(|(_, s)| s).unwrap_or(mime)
}
fn media_to_content_block_json(media: &BamlMedia) -> Result<serde_json::Value> {
let content_block = {
let mut obj = Map::new();
if let Some(mime) = media.mime_type.as_deref() {
obj.insert("format".into(), json!(strip_mime_prefix(mime)));
}
let source = match &media.content {
BamlMediaContent::File(media_file) => todo!(),
BamlMediaContent::Url(url) => {
let parsed = Url::parse(&url.url).with_context(|| {
format!("Invalid S3 URI for AWS Bedrock video source: {url}")
})?;
if parsed.scheme() != "s3" {
anyhow::bail!("AWS Bedrock requires s3:// URIs, but got: {}", url.url);
}
// unimplemented!("make sure the test works")
json!({
"s3Location": {
"uri": url.url,
}
})
}
BamlMediaContent::Base64(base64) => json!({
"bytes": base64.base64,
}),
};
obj.insert("source".into(), source);
obj
};
match media.media_type {
// _ => anyhow::bail!("AWS Bedrock only supports base64 image inputs in modular requests"),View on GitHub (pinned to bd85ce9dee)
Solutions
- Upload the media to S3 and reference it as s3://bucket-name/key (with a valid bucket in the same region the model is invoked in).
- Or send the media as a base64 data URL so it goes through the bytes path instead of s3Location.
- Verify the URI parses and has scheme 's3' before calling the client (note: a bare bucket name is not valid; the scheme must be s3).
Example fix
// before media video "https://mybucket.s3.amazonaws.com/clip.mp4" // after media video "s3://mybucket/clip.mp4"
Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlparse
url = media['content']['url']
if urlparse(url).scheme != 's3':
raise ValueError(f"Bedrock video source must be s3:// URI, got {url}") Type guard
def is_s3_uri(u: str) -> bool:
return u.lower().startswith('s3://') Prevention
- Standardize on s3://bucket/key URIs for URL-based media on Bedrock
- Upload https-hosted media to S3 (or base64-inline it) when switching providers to aws-bedrock
- Add a prompt-level test that renders media with the aws-bedrock client
When it happens
Trigger: Passing a media part with BamlMediaContent::Url whose url does not start with s3:// (e.g. a public https URL or a malformed 's3:/bucket/key') while targeting an aws-bedrock client.
Common situations: Reusing prompt media (https URLs) that worked with OpenAI/Anthropic providers on a Bedrock client; writing S3 URIs without the double slash; referencing presigned CloudFront URLs instead of S3 URIs.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- AWS Bedrock only supports text system blocks, but got {other
- not yet implemented
- Invalid client property. Should have been a aws-bedrock prop
- AWS Bedrock modular streaming is not supported. Use non-stre
- AWS region is required to build modular request. Set it in t
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/c5c3a81257d9de00.
Report an issue: GitHub.