BoundaryML/baml · error · anyhow::Error
Non-text part encountered
Error message
Non-text part encountered
What it means
This path combines all message parts by mapping each part to its text, and errors if any part is not ChatMessagePart::Text. It is used where only plain-text messages are valid, so media or structured parts cannot be represented.
Source
Thrown at engine/baml-runtime/src/internal/llm_client/primitive/openai/openai_client.rs:371
Ok(json!(parts_to_message(&content.parts)?))
}
ProviderStrategy::StandardOpenAI { provider } => {
if provider == "openai-generic" {
// Check if all parts are text
let all_text = content
.parts
.iter()
.all(|part| matches!(part, ChatMessagePart::Text(_)));
if all_text {
// Concatenate all text parts into a single string
let combined_text = content
.parts
.iter()
.map(|part| {
if let ChatMessagePart::Text(text) = part {
Ok(text.clone())
} else {
Err(anyhow::anyhow!("Non-text part encountered"))
}
})
.collect::<Result<Vec<String>>>()?
.join(" ");
Ok(json!(combined_text))
} else {
// If there are media parts, use the existing structure
Ok(json!(parts_to_message(&content.parts)?))
}
} else {
// For other providers, use the existing structure
Ok(json!(parts_to_message(&content.parts)?))
}
}
}
}
}View on GitHub (pinned to bd85ce9dee)
Solutions
- Ensure the prompt contains only text parts for this provider strategy
- Move media blocks to a provider/endpoint that supports them (chat completions with media)
- Strip or conditionally exclude media from the message before rendering
Example fix
// before
message { media { type image url ctx.img } }
// after
message { "describe the scene" } // text-only for this path Defensive patterns
Strategy: validation
Validate before calling
// ensure all parts are text before this path
const allText = msg.parts.every(p => typeof p === "string" || p.type === "text");
if (!allText) throw new Error("Only text parts allowed for this provider path"); Type guard
function isTextPart(p: unknown): p is { type: "text"; text: string } {
return typeof p === "object" && p !== null && (p as any).type === "text";
} Prevention
- Keep media out of prompts rendered for text-only provider paths
- Validate rendered messages for media parts in tests
When it happens
Trigger: format_message_content called on a message whose parts include non-text ChatMessagePart variants (Image, Audio, WithMeta, etc.) while the code path requires text-only parts.
Common situations: Passing an image or audio media block into a provider/endpoint path that only accepts plain text messages (e.g. certain completion formats that concatenate text).
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- BAML internal error (openai-responses): video is not yet sup
- Video input is only supported on OpenAI's Realtime API (/v1/
- base_url is required
- Invalid OpenAI client provider variant: {}
- Video input is not yet supported by Anthropic Claude models.
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/0185b824ca11d1c3.
Report an issue: GitHub.