Skip to content

Python: [Bug]: BedrockChatClient drops images from user messages, so GPT-6 Sol/Luna/Astra answer without seeing them #8682

Description

@kimnamu

Description

Thanks for the Bedrock connector and for the careful tool-result handling in _convert_content_to_bedrock_block. As far as I can tell, image content in a user message (Content.from_data(..., media_type="image/png")) is dropped before the Converse call, so the model answers without seeing the image. I noticed it while trying the new OpenAI GPT-6 Sol/Luna/Astra models, which accept image input on Bedrock.

Red 64x64 PNG + "What color is this image? One word.", us-east-1 BedrockChatClient (main @ f42ff01) Raw boto3 converse, same bytes
us.openai.gpt-6-sol ❌ 'Unknown.', user blocks sent: ['text'] 'Red'
us.openai.gpt-6-luna ❌ 'Gray', user blocks sent: ['text'] 'Red'
us.openai.gpt-5.6-sol ❌ 'Unknown', user blocks sent: ['text'] 'Red'
us.openai.gpt-6-astra ❌ 'Unknown.', user blocks sent: ['text'] 'Red'
global.openai.gpt-6-astra ❌ 'Unknown', user blocks sent: ['text'] 'Red'

The guesses vary between runs (Luna also said 'Black.'); the image is never sent.

Where: _convert_content_to_bedrock_block in python/packages/bedrock/agent_framework_bedrock/_chat_client.py (L549-585) matches text, function_call and function_result; everything else hits case _ ("Bedrock does not support other content types at this time") and is skipped with a debug log (L544). Converse accepts image blocks with raw bytes. The Anthropic client already maps image data content via has_top_level_media_type("image"), and Gemini uses _get_data_bytes for the bytes.

Impact: vision use cases silently send a text-only request and the model still answers, so it looks like a model quality problem. The drop happens before any model is called, so it isn't specific to GPT-6.

Suggested fix: for user messages, add a case "data" if content.has_top_level_media_type("image") branch that returns {"image": {"format": <subtype>, "source": {"bytes": _get_data_bytes(content)}}}. Images in assistant messages and other data types stay skipped as today. I have a small PR with regression tests and will link it here.

Code Sample

import asyncio, pathlib
from agent_framework import Content, Message
from agent_framework.amazon import BedrockChatClient

async def main():
    client = BedrockChatClient(model="us.openai.gpt-6-sol", region="us-east-1")
    png = pathlib.Path("red.png").read_bytes()  # 64x64 red
    msg = Message(role="user", contents=[
        Content.from_text("What color is this image? One word."),
        Content.from_data(data=png, media_type="image/png"),
    ])
    print((await client.get_response([msg])).text)

asyncio.run(main())

Error Messages / Stack Traces

# BedrockChatClient, main @ f42ff01 (request captured with a botocore provide-client-params hook)
us.openai.gpt-6-sol -> 'Unknown.' | user blocks sent ['text']
us.openai.gpt-6-luna -> 'Gray' | user blocks sent ['text']
us.openai.gpt-5.6-sol -> 'Unknown' | user blocks sent ['text']
us.openai.gpt-6-astra -> 'Unknown.' | user blocks sent ['text']
global.openai.gpt-6-astra -> 'Unknown' | user blocks sent ['text']

# raw boto3 converse, same PNG
us.openai.gpt-6-sol raw image -> ['Red']
us.openai.gpt-6-luna raw image -> ['Red']
us.openai.gpt-5.6-sol raw image -> ['Red']
us.openai.gpt-6-astra raw image -> ['Red']
global.openai.gpt-6-astra raw image -> ['Red']

No error is raised; only a debug log line.

Package Versions

agent-framework-core: 1.19.0, agent-framework-bedrock: 1.0.0b260918 (main @ f42ff01), boto3: 1.43.100

Python Version

Python 3.12

Additional Context

Why only user messages, and what is out of scope

An image block in an assistant message is rejected by GPT-6 Sol, Luna and Astra on Converse: ValidationException: This model doesn't support the image content block that you provided. Main skips those today and the request succeeds, so the fix keeps skipping them.

Images inside tool results are a separate path (dropped with a warning on purpose). HTTP image URLs are also out of scope, because Converse takes only bytes or an S3 location.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

agentsUsage: [Issues, PRs], Target: Single agentpythonUsage: [Issues, PRs], Target: PythonreproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflow

Type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions