Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

GoogleModel generates empty text parts that Vertex AI rejects with 400 error #2032

Closed
Assignees
DouweM
@Infinnerty

Description

@Infinnerty

Initial Checks

Description

When usingGoogleModel with Vertex AI, requests fail with a 400 error becausepydantic_ai generates empty text parts{'text': ''} that Google's API rejects.

Error Message

400Bad Request. {"error": {"code":400,"message":"Unable to submit request because it must have a text parameter. Add a text parameter and try again. Learn more: https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/gemini","status":"INVALID_ARGUMENT"  }}

Root Cause

Inpydantic_ai/models/google.py, the_map_messages() method at lines 362-364 adds empty text parts as a defensive measure:

# Google GenAI requires at least one part in the message.ifnotmessage_parts:message_parts= [{'text':''}]

However, Google's Vertex AI API strictly validates thetext parameter and rejects empty strings, requiring non-empty text content.

Reproduction

This occurs when:

  • Messages have no content after processing
  • Message parts arrays become empty during conversion
  • Certain edge cases in message handling

Impact

  • Affects all users ofGoogleModel with Vertex AI
  • Causes complete request failures with 400 errors
  • Blocks streaming and non-streaming requests

Suggested Fix

Replace the empty string with a minimal valid text:

# Instead of:ifnotmessage_parts:message_parts= [{'text':''}]# Use:ifnotmessage_parts:message_parts= [{'text':' '}]# Single space

Or add provider-specific handling for Google's stricter validation requirements.

Temporary Workaround

We've implemented a subclass that filters empty text parts:

classFixedGoogleModel(GoogleModel):asyncdef_map_messages(self,messages):system_instruction,contents=awaitsuper()._map_messages(messages)# Filter out empty text parts and ensure valid structurecleaned_contents= []forcontent_itemincontents:if"parts"notincontent_item:cleaned_contents.append(content_item)continueoriginal_parts=content_item.get("parts", [])cleaned_parts= [partforpartinoriginal_partsifnot (isinstance(part,dict)andpart.get("text")==""andlen(part)==1)            ]ifnotcleaned_parts:cleaned_parts= [{"text":" "}]content_item["parts"]=cleaned_partscleaned_contents.append(content_item)ifnotcleaned_contents:cleaned_contents= [{"role":"user","parts": [{"text":" "}]}]returnsystem_instruction,cleaned_contents

This workaround successfully resolves the 400 errors while maintaining API compatibility.

Example Code

importasynciofrompydantic_aiimportAgentfrompydantic_ai.models.googleimportGoogleModelfrompydantic_ai.providers.googleimportGoogleProviderasyncdefreproduce_bug():# Set up GoogleModel with Vertex AIprovider=GoogleProvider(vertexai=True,location="us-central1"# or your preferred location    )model=GoogleModel("gemini-pro-2.5",provider=provider)# Create an agentagent=Agent(model=model)# This scenario can trigger empty message parts# Case 1: Empty string messagetry:result=awaitagent.run("")print("Empty string succeeded:",result)exceptExceptionase:print("Empty string failed:",str(e))# Case 2: Message that becomes empty after processingtry:result=awaitagent.run("   ")# Only whitespaceprint("Whitespace succeeded:",result)exceptExceptionase:print("Whitespace failed:",str(e))# Run the reproductionif__name__=="__main__":asyncio.run(reproduce_bug())

Python, Pydantic AI & LLM client version

Pydantic AI version: v0.3.1Python version: 3.12Provider: Google Vertex AIModel: gemini-pro-2.5 (via GoogleModel/Vertex)

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions


    [8]ページ先頭

    ©2009-2025 Movatter.jp