Skip to content

fix: handle missing optional fields in non-streaming citation conversion#2098

Merged
mkmeral merged 1 commit intostrands-agents:mainfrom
agent-of-mkmeral:agent-tasks/fix-citation-keyerror
Apr 9, 2026
Merged

fix: handle missing optional fields in non-streaming citation conversion#2098
mkmeral merged 1 commit intostrands-agents:mainfrom
agent-of-mkmeral:agent-tasks/fix-citation-keyerror

Conversation

@agent-of-mkmeral
Copy link
Copy Markdown
Contributor

Non-streaming Bedrock responses with citationsContent crash with KeyError: 'title' when Nova grounding returns citations without optional fields.

Why

Nova's web grounding returns citations containing only location (with url and domain) but no title or sourceContent fields. The _convert_non_streaming_to_streaming method accesses these fields directly (citation["title"]), causing a KeyError.

The SDK's own CitationsDelta type is TypedDict(total=False) — all fields are optional. And the same file already handles this correctly in _format_request_message_content using if "title" in citation checks. The non-streaming conversion path was the only place that didn't follow this pattern.

What changed

src/strands/models/bedrock.py — Changed _convert_non_streaming_to_streaming to conditionally include citation fields only when present, matching the existing safe pattern elsewhere in the file.

tests/strands/models/test_bedrock.py — Added three test cases:

  • Citations with missing optional fields (the Nova grounding case)
  • Citations with all fields present (regression guard)
  • Citations with only location (minimal citation)

Reproduction

from strands import Agent
from strands.models import BedrockModel

model = BedrockModel(
    model_id="us.amazon.nova-2-lite-v1:0",
    region_name="us-east-1",
    streaming=False,
    additional_args={
        "toolConfig": {"tools": [{"systemTool": {"name": "nova_grounding"}}]}
    },
)
agent = Agent(model=model, tools=[])
result = agent("top 5 shoe brands")  # KeyError: 'title'

Related: #1154, #1318, #1323

Nova grounding returns citations with only url/domain in location but
no title or sourceContent fields. The non-streaming to streaming
conversion in _convert_non_streaming_to_streaming accessed these fields
directly (citation["title"]) causing KeyError.

Changed to conditional inclusion using 'in' checks, matching the
existing pattern in _format_request_message_content (line 668) and
consistent with CitationsDelta being TypedDict(total=False).
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 9, 2026

Codecov Report

❌ Patch coverage is 85.71429% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/strands/models/bedrock.py 85.71% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@mkmeral mkmeral merged commit 762fba2 into strands-agents:main Apr 9, 2026
17 of 20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants