Skip to content

fix: unwrap single-variant anyOf to preserve sibling fields in Vertex AI schema#19270

Open
VedantMadane wants to merge 1 commit intoBerriAI:mainfrom
VedantMadane:fix/vertex-ai-anyof-sibling-fields
Open

fix: unwrap single-variant anyOf to preserve sibling fields in Vertex AI schema#19270
VedantMadane wants to merge 1 commit intoBerriAI:mainfrom
VedantMadane:fix/vertex-ai-anyof-sibling-fields

Conversation

@VedantMadane
Copy link
Contributor

Relevant issues

Fixes #19255

Summary

When Pydantic generates Optional[X], it creates:

{
  "anyOf": [{"type": "integer", "minimum": 0}, {"type": "null"}],
  "default": null,
  "examples": [7, 30, 90],
  "description": "Filter by number of days"
}

The constraints (default, examples, pattern) are siblings of anyOf.

After convert_anyof_null_to_nullable removes the null type, if only ONE variant remains in anyOf, we now unwrap it and merge the sibling fields. This prevents _filter_anyof_fields from stripping them.

Before (sibling fields lost):

{"anyOf": [{"type": "integer", "minimum": 0}], "default": null, "examples": [...]}
-> {"anyOf": [{"type": "integer", "minimum": 0, "nullable": true}]}
// default and examples are LOST!

After (sibling fields preserved):

{"anyOf": [{"type": "integer", "minimum": 0}], "default": null, "examples": [...]}
-> {"type": "integer", "minimum": 0, "nullable": true, "default": null, "examples": [...]}

Pre-Submission checklist

  • I have Added testing in the tests/litellm/ directory - Added test_anyof_conversion_preserves_sibling_fields
  • All existing tests pass (schema-related tests all pass)

Changes

  1. litellm/llms/vertex_ai/common_utils.py:

    • Modified convert_anyof_null_to_nullable to unwrap single-variant anyOf arrays and merge sibling fields
  2. tests/test_litellm/llms/vertex_ai/test_vertex_ai_common_utils.py:

    • Added test_anyof_conversion_preserves_sibling_fields to verify the fix
    • Updated test_basic_anyof_conversion to expect unwrapped single-variant anyOf
    • Updated test_build_vertex_schema and test_build_vertex_schema_empty_properties to reflect new behavior

… AI schema

Fixes BerriAI#19255

When Pydantic generates Optional[X], it creates:
  anyOf: [{X schema}, {type: null}]
with constraints (default, examples, pattern) as siblings.

After convert_anyof_null_to_nullable removes the null type, if only ONE
variant remains, we now unwrap it and merge the sibling fields. This
prevents _filter_anyof_fields from stripping them.

Before:
  {anyOf: [{type: int, nullable: true}], default: None, examples: [...]}
  -> {anyOf: [{type: int, nullable: true}]}  (siblings lost!)

After:
  {anyOf: [{type: int, nullable: true}], default: None, examples: [...]}
  -> {type: int, nullable: true, default: None, examples: [...]}

Added test: test_anyof_conversion_preserves_sibling_fields
Updated tests: test_basic_anyof_conversion, test_build_vertex_schema,
               test_build_vertex_schema_empty_properties
@CLAassistant
Copy link

CLAassistant commented Jan 17, 2026

CLA assistant check
All committers have signed the CLA.

@vercel
Copy link

vercel bot commented Jan 17, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
litellm Error Error Jan 17, 2026 8:02am

Request Review

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Vertex AI schema transformation strips sibling fields from Optional types - single-variant anyOf should be unwrapped

2 participants