{"record":{"id":"0185b824ca11d1c3","repo":"BoundaryML/baml","slug":"non-text-part-encountered","errorCode":null,"errorMessage":"Non-text part encountered","messagePattern":"Non-text part encountered","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"engine/baml-runtime/src/internal/llm_client/primitive/openai/openai_client.rs","lineNumber":371,"sourceCode":"                Ok(json!(parts_to_message(&content.parts)?))\n            }\n            ProviderStrategy::StandardOpenAI { provider } => {\n                if provider == \"openai-generic\" {\n                    // Check if all parts are text\n                    let all_text = content\n                        .parts\n                        .iter()\n                        .all(|part| matches!(part, ChatMessagePart::Text(_)));\n                    if all_text {\n                        // Concatenate all text parts into a single string\n                        let combined_text = content\n                            .parts\n                            .iter()\n                            .map(|part| {\n                                if let ChatMessagePart::Text(text) = part {\n                                    Ok(text.clone())\n                                } else {\n                                    Err(anyhow::anyhow!(\"Non-text part encountered\"))\n                                }\n                            })\n                            .collect::<Result<Vec<String>>>()?\n                            .join(\" \");\n\n                        Ok(json!(combined_text))\n                    } else {\n                        // If there are media parts, use the existing structure\n                        Ok(json!(parts_to_message(&content.parts)?))\n                    }\n                } else {\n                    // For other providers, use the existing structure\n                    Ok(json!(parts_to_message(&content.parts)?))\n                }\n            }\n        }\n    }\n}","sourceCodeStart":353,"sourceCodeEnd":389,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-runtime/src/internal/llm_client/primitive/openai/openai_client.rs#L353-L389","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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"],"exampleFix":"// before\nmessage { media { type image url ctx.img } }\n// after\nmessage { \"describe the scene\" } // text-only for this path","handlingStrategy":"validation","validationCode":"// ensure all parts are text before this path\nconst allText = msg.parts.every(p => typeof p === \"string\" || p.type === \"text\");\nif (!allText) throw new Error(\"Only text parts allowed for this provider path\");","typeGuard":"function isTextPart(p: unknown): p is { type: \"text\"; text: string } {\n  return typeof p === \"object\" && p !== null && (p as any).type === \"text\";\n}","tryCatchPattern":null,"preventionTips":["Keep media out of prompts rendered for text-only provider paths","Validate rendered messages for media parts in tests"],"tags":["openai","message-format","text-only","unsupported-media"],"backgroundTag":"invalid-argument-value","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}