BoundaryML/baml · error

Expected message output to contain at least one text block…

Error message

Expected message output to contain at least one text block, but found none. Content: {:?}

What it means

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.

Solutions

  1. Disable tool configuration in the request (or ensure the model is instructed to answer in text) so Bedrock returns a Text content block.
  2. If using tool use, handle toolUse blocks in your application and send tool results back until the model emits a final text message.
  3. Inspect the error's Content listing to see which block types were returned and adjust the prompt/model accordingly.

Example fix

// before
options { model my-model toolConfig { ... } }  // model answers via toolUse
// after
options { model my-model }  // text-only response, or handle toolUse blocks yourself
Defensive patterns

Strategy: type-guard

Validate before calling

# ensure tool config is disabled when plain-text output is expected
assert 'toolConfig' not in bedrock_client_options, "toolConfig forces toolUse blocks; BAML chat expects text"

Type guard

def response_is_text_only(blocks) -> bool:
    return any(b.get('text') for b in blocks) and all('toolUse' not in b for b in blocks)

Try / catch

try:
    out = baml_client.MyFunction(...)
except Exception as e:
    if 'at least one text block' in str(e):
        # response contained only toolUse/non-text blocks — disable tools or handle them
        raise RuntimeError('Model answered with tool calls; disable toolConfig or loop on tool results') from e
    raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/ed3f9292b27f85b6. Report an issue: GitHub.

Appendix: source

Thrown at engine/baml-runtime/src/internal/llm_client/primitive/aws/aws_client.rs:713

        if message.content.is_empty() {
            anyhow::bail!("Expected message output to have content, but content is empty");
        }

        for content_block in &message.content {
            if let bedrock::types::ContentBlock::Text(text) = content_block {
                has_text = true;
                extracted_text.push_str(text);
            }
        }

        // If we found at least one text block, return the concatenated text
        if has_text {
            let content = extracted_text;
            return Ok(content);
        }

        // If we didn't find any text blocks, return an error with details about the content
        anyhow::bail!(
            "Expected message output to contain at least one text block, but found none. Content: {:?}",
            message.content.iter().map(|block| match block {
                bedrock::types::ContentBlock::Image(_) => "image",
                bedrock::types::ContentBlock::GuardContent(_) => "guardContent",
                bedrock::types::ContentBlock::ToolResult(_) => "toolResult",
                bedrock::types::ContentBlock::ToolUse(_) => "toolUse",
                bedrock::types::ContentBlock::Text(_) => "text",
                bedrock::types::ContentBlock::ReasoningContent(_) => "reasoningContent",
                bedrock::types::ContentBlock::CachePoint(_) => "cachePoint",
                bedrock::types::ContentBlock::Document(_) => "document",
                bedrock::types::ContentBlock::Video(_) => "video",
                _ => "unknown",
            }).collect::<Vec<_>>()
        );
    }

    fn build_request(
        &self,

View on GitHub (pinned to bd85ce9dee)