sdk-python icon indicating copy to clipboard operation
sdk-python copied to clipboard

[BUG] Bedrock Runtime API CitationLocation Tagged Union Structure Error

Open Tarun02 opened this issue 6 days ago • 3 comments

Checks

  • [x] I have updated to the lastest minor and patch version of Strands
  • [x] I have checked the documentation and this is not expected behavior
  • [x] I have searched ./issues and there are no duplicates of my issue

Strands Version

1.19.0

Python Version

3.14.2

Operating System

N/A

Installation Method

pip

Steps to Reproduce

Minimum Reproducible code

from strands.models.bedrock import BedrockModel
import asyncio

async def processing_streaming_response():
    model = BedrockModel(
        model_id="us.anthropic.claude-3-7-sonnet-20250219-v1:0"
    )

    messages = [
        {
            "role": "user",
            "content": [
                {
                    "text": "Use this media in your response."
                }
            ]
        },
        # Assistant response with citations
        {
            "role": "assistant",
            "content": [
                {
                    "text": "I've analyzed the document. Here's what I found:"
                },
                {
                    "citationsContent": {
                        "citations": [
                            {
                                "location": {
                                    "documentChar": {
                                        "documentIndex": 0,
                                        "start": 150,
                                        "end": 300
                                    }
                                },
                                "sourceContent": [
                                    {
                                        "text": "Employee benefits include health insurance and retirement plans"
                                    }
                                ],
                                "title": "Benefits Section"
                            },
                            {
                                "location": {
                                    "documentPage": {
                                        "documentIndex": 0,
                                        "start": 2,
                                        "end": 3
                                    }
                                },
                                "sourceContent": [
                                    {
                                        "text": "Vacation policy allows 15 days per year"
                                    }
                                ],
                                "title": "Vacation Policy"
                            }
                        ],
                        "content": [
                            {
                                "text": "Based on the document, employees receive comprehensive benefits including health insurance, retirement plans, and 15 days of vacation per year."
                            }
                        ]
                    }
                }
            ]
        }
    ]

    #model._format_bedrock_messages(messages=messages)
    response_text = ""
    async for chunk in model.stream(
        messages=messages
    ):
        #response_text += chunk
        print(chunk, end="", flush=True)

    return response_text

asyncio.run(processing_streaming_response())
  • Install strands through this command: pip install strands-agents strands-tools
  • Run the code, and you will observe the following error:
botocore.exceptions.ParamValidationError: Parameter validation failed:
Must set one of the following keys for tagged unionstructure messages[1].content[1].citationsContent.citations[0].location: web, documentChar, documentPage, documentChunk, searchResultLocation.
Must set one of the following keys for tagged unionstructure messages[1].content[1].citationsContent.citations[1].location: web, documentChar, documentPage, documentChunk, searchResultLocation.

Expected Behavior

  • CitationLocation objects should preserve the tagged union structure required by AWS Bedrock Runtime API: https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_CitationLocation.html

Actual Behavior

  • It is not doing that but expecting all the keys should be present in the API.

Additional Context

No response

Possible Solution

  • Preserve the union structure when processing CitationLocation objects.
  • Sample code below(need to test it out):
def _format_citation_location(location: dict) -> dict:
    """Preserve tagged union structure for AWS Bedrock API compatibility"""
    
    # Check which union type is present and preserve wrapper
    if "documentChar" in location:
        inner = location["documentChar"]
        filtered_inner = {}
        if "documentIndex" in inner:
            filtered_inner["documentIndex"] = inner["documentIndex"]
        if "start" in inner:
            filtered_inner["start"] = inner["start"]
        if "end" in inner:
            filtered_inner["end"] = inner["end"]
        return {"documentChar": filtered_inner}
    
    elif "documentPage" in location:
        # Similar processing for documentPage union type
        return {"documentPage": filtered_inner}
    
    # Handle other union types: documentChunk, searchResultLocation, web
    # ...
    
    else:
        # Fallback: infer union type from available fields
        if "url" in location:
            return {"web": {"url": location["url"]}}
        # Default to documentChar for document locations
        return {"documentChar": location}

Related Issues

No response

Tarun02 avatar Dec 13 '25 05:12 Tarun02