microsoft/semantic-kernel · error · ServiceInvalidRequestError

ImageContent without data_uri in User message while formatti

Error message

ImageContent without data_uri in User message while formatting chat history for Google AI

What it means

Raised by _create_image_part when an ImageContent has no data_uri. The Gemini API does not support fetching images from arbitrary URIs (see the linked google-gemini issue); it only accepts inline image bytes. When data_uri is set, the formatter reads image_content.data and mime_type to construct Part.from_bytes. Without data_uri, there is no inline data to send and the request cannot proceed.

Source

Thrown at python/semantic_kernel/connectors/ai/google/google_ai/services/utils.py:201

            }
        }
        settings.tools = [
            {
                "function_declarations": [
                    kernel_function_metadata_to_google_ai_function_call_format(f)
                    for f in function_choice_configuration.available_functions
                ]
            }
        ]


def _create_image_part(image_content: ImageContent) -> Part:
    if image_content.data_uri:
        return Part.from_bytes(data=image_content.data, mime_type=image_content.mime_type)  # type: ignore[arg-type]

    # The Google AI API doesn't support images from arbitrary URIs:
    # https://github.com/google-gemini/generative-ai-python/issues/357
    raise ServiceInvalidRequestError(
        "ImageContent without data_uri in User message while formatting chat history for Google AI"
    )

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Provide inline image data: ImageContent(data=image_bytes, mime_type='image/png', data_uri='data:image/png;base64,...').
  2. If you have a URL, download the image bytes first and pass them as inline data with a data_uri.
  3. Set data_uri to a truthy value whenever ImageContent.data is populated, so the formatter uses the inline-bytes path.

Example fix

# before
img = ImageContent(uri='https://example.com/cat.png')  # no inline data
history.add_user_message(items=[TextContent(text='what is this?'), img])

# after
import httpx, base64
resp = httpx.get('https://example.com/cat.png')
b64 = base64.b64encode(resp.content).decode()
img = ImageContent(data=resp.content, mime_type='image/png', data_uri=f'data:image/png;base64,{b64}')
history.add_user_message(items=[TextContent(text='what is this?'), img])
Defensive patterns

Strategy: validation

Validate before calling

def validate_image_content(image_content):
    if not image_content.data_uri:
        raise ValueError('ImageContent requires inline data_uri for Google AI; remote URIs are not supported.')
    if not image_content.data:
        raise ValueError('ImageContent.data is empty; provide inline image bytes.')

Type guard

def is_valid_google_ai_image(image_content) -> bool:
    return bool(getattr(image_content, 'data_uri', None)) and bool(getattr(image_content, 'data', None))

Prevention

When it happens

Trigger: Adding an ImageContent to a user or assistant message with only a uri (remote URL or local path) but no data_uri / inline data, then calling a chat completion method.

Common situations: Constructing ImageContent(uri='https://...') expecting the API to fetch it (Gemini does not support this); passing ImageContent(data=b'...') without setting data_uri; migrating from an OpenAI connector that accepts URL-based images.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/d69d5da977229fac. Report an issue: GitHub.