BoundaryML/baml · error
AWS Bedrock only supports text system blocks, but got {other
Error message
AWS Bedrock only supports text system blocks, but got {other:?} What it means
system_part_to_json only knows how to render system prompt parts that are plain text (or text wrapped in metadata for cache_control). If a system message part is some other variant (e.g. media, image, or tool content in the system role), the client bails because the Bedrock Converse 'system' field accepts only text blocks (plus cachePoint).
Source
Thrown at engine/baml-runtime/src/internal/llm_client/primitive/aws/aws_client.rs:136
fn cache_point_json() -> serde_json::Value {
json!({"cachePoint": {"type": "default"}})
}
fn system_part_to_json(
part: &ChatMessagePart,
allowed_metadata: &AllowedRoleMetadata,
) -> Result<Vec<serde_json::Value>> {
match part {
ChatMessagePart::Text(t) => Ok(vec![json!({ "text": t })]),
ChatMessagePart::WithMeta(p, meta) => {
let mut blocks = system_part_to_json(p, allowed_metadata)?;
if allowed_metadata.is_allowed("cache_control") && meta.contains_key("cache_control") {
blocks.push(cache_point_json());
}
Ok(blocks)
}
other => anyhow::bail!("AWS Bedrock only supports text system blocks, but got {other:?}"),
}
}
fn chat_part_to_json(
part: &ChatMessagePart,
allowed_metadata: &AllowedRoleMetadata,
) -> Result<Vec<serde_json::Value>> {
match part {
ChatMessagePart::Text(t) => Ok(vec![json!({ "text": t })]),
ChatMessagePart::Media(media) => Ok(vec![media_to_content_block_json(media)?]),
ChatMessagePart::WithMeta(inner, meta) => {
let mut blocks = chat_part_to_json(inner, allowed_metadata)?;
if allowed_metadata.is_allowed("cache_control") && meta.contains_key("cache_control") {
blocks.push(cache_point_json());
}
Ok(blocks)
}
}View on GitHub (pinned to bd85ce9dee)
Solutions
- Move any media or non-text content out of the system role into a user/assistant message, keeping the system prompt text-only.
- Ensure tool definitions are passed via the provider's tool parameter mechanism, not embedded in system message parts.
- If you need prompt caching, attach cache_control metadata to the text system part (it is converted to a cachePoint block) rather than changing the part type.
Example fix
// before
message System { {{ctx_image}} You are helpful. }
// after
message System { You are helpful. }
message User { {{ctx_image}} Describe this. } Defensive patterns
Strategy: validation
Validate before calling
for part in system_message['parts']:
if part['type'] != 'text':
raise ValueError(f"aws-bedrock system prompt must be text-only, got {part['type']}") Type guard
def is_text_system_message(msg) -> bool:
return all(p.get('type') == 'text' for p in msg.get('parts', [])) Prevention
- Keep system prompts text-only; put media in user messages
- Never embed tool definitions or results in the system role
- Review prompt templates when porting from other providers to aws-bedrock
When it happens
Trigger: Rendering a chat where the system role message contains a non-text part — e.g. an image/media part placed in the system prompt, or tool-call content in the system role — when building the Converse request body for aws-bedrock.
Common situations: Migrating prompts written for providers that tolerate images in the system prompt (some Anthropic setups) to Bedrock; accidentally passing a media block into the system message via templating; putting tool definitions/results in the system role.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- AWS Bedrock requires s3:// URIs, but got: {}
- AWS Bedrock modular streaming is not supported. Use non-stre
- unsupported blob algorithm `{}`
- not yet implemented
- Invalid client property. Should have been a aws-bedrock prop
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/ab335e03fe262e0a.
Report an issue: GitHub.