{"record":{"id":"ed3f9292b27f85b6","repo":"BoundaryML/baml","slug":"expected-message-output-to-contain-at-least-one-text-block","errorCode":null,"errorMessage":"Expected message output to contain at least one text block, but found none. Content: {:?}","messagePattern":"Expected message output to contain at least one text block, but found none\\. Content: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-runtime/src/internal/llm_client/primitive/aws/aws_client.rs","lineNumber":713,"sourceCode":"        if message.content.is_empty() {\n            anyhow::bail!(\"Expected message output to have content, but content is empty\");\n        }\n\n        for content_block in &message.content {\n            if let bedrock::types::ContentBlock::Text(text) = content_block {\n                has_text = true;\n                extracted_text.push_str(text);\n            }\n        }\n\n        // If we found at least one text block, return the concatenated text\n        if has_text {\n            let content = extracted_text;\n            return Ok(content);\n        }\n\n        // If we didn't find any text blocks, return an error with details about the content\n        anyhow::bail!(\n            \"Expected message output to contain at least one text block, but found none. Content: {:?}\",\n            message.content.iter().map(|block| match block {\n                bedrock::types::ContentBlock::Image(_) => \"image\",\n                bedrock::types::ContentBlock::GuardContent(_) => \"guardContent\",\n                bedrock::types::ContentBlock::ToolResult(_) => \"toolResult\",\n                bedrock::types::ContentBlock::ToolUse(_) => \"toolUse\",\n                bedrock::types::ContentBlock::Text(_) => \"text\",\n                bedrock::types::ContentBlock::ReasoningContent(_) => \"reasoningContent\",\n                bedrock::types::ContentBlock::CachePoint(_) => \"cachePoint\",\n                bedrock::types::ContentBlock::Document(_) => \"document\",\n                bedrock::types::ContentBlock::Video(_) => \"video\",\n                _ => \"unknown\",\n            }).collect::<Vec<_>>()\n        );\n    }\n\n    fn build_request(\n        &self,","sourceCodeStart":695,"sourceCodeEnd":731,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-runtime/src/internal/llm_client/primitive/aws/aws_client.rs#L695-L731","documentation":"chat_anyhow iterates the message's content blocks collecting Text blocks; if none of the blocks are text (all are image, toolUse, toolResult, guardContent, etc.), it bails with this error, which includes a rendered list of the block types present. BAML's chat extraction only handles text output, so a response consisting purely of tool-use or non-text blocks cannot be returned as a string.","triggerScenarios":"The model responds with only non-text content blocks — e.g. toolUse blocks when tool config is set, toolResult echoes, or guardContent — during a chat call on an aws-bedrock client.","commonSituations":"Enabling Bedrock tool use / function calling on a client whose BAML function expects plain text output; proxying to a model that returns reasoning/tool blocks only; misconfigured request that triggers tool invocation instead of a text answer.","solutions":["Disable tool configuration in the request (or ensure the model is instructed to answer in text) so Bedrock returns a Text content block.","If using tool use, handle toolUse blocks in your application and send tool results back until the model emits a final text message.","Inspect the error's Content listing to see which block types were returned and adjust the prompt/model accordingly."],"exampleFix":"// before\noptions { model my-model toolConfig { ... } }  // model answers via toolUse\n// after\noptions { model my-model }  // text-only response, or handle toolUse blocks yourself","handlingStrategy":"type-guard","validationCode":"# ensure tool config is disabled when plain-text output is expected\nassert 'toolConfig' not in bedrock_client_options, \"toolConfig forces toolUse blocks; BAML chat expects text\"","typeGuard":"def response_is_text_only(blocks) -> bool:\n    return any(b.get('text') for b in blocks) and all('toolUse' not in b for b in blocks)","tryCatchPattern":"try:\n    out = baml_client.MyFunction(...)\nexcept Exception as e:\n    if 'at least one text block' in str(e):\n        # response contained only toolUse/non-text blocks — disable tools or handle them\n        raise RuntimeError('Model answered with tool calls; disable toolConfig or loop on tool results') from e\n    raise","preventionTips":["Don't enable Bedrock tool use on clients whose BAML function expects plain text","If tools are required, implement the tool-use loop in application code until a text block appears","Inspect the Content type list in the error message to identify what the model returned"],"tags":["aws","bedrock","response","tool-use","text"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}