Skip to content

fix: strip $schema and convert array types in Gemini schema conversion#5585

Merged
colegottdank merged 1 commit intomainfrom
fix/gemini-schema-strip-fields
Feb 19, 2026
Merged

fix: strip $schema and convert array types in Gemini schema conversion#5585
colegottdank merged 1 commit intomainfrom
fix/gemini-schema-strip-fields

Conversation

@colegottdank
Copy link
Collaborator

Summary

Fixes 400 errors on Gemini model requests with structured output/response_format:

  • Strip $schema field from JSON schemas (Gemini doesn't recognize it)
  • Convert array types like ["string", "null"] to type: "string" + nullable: true

Errors fixed

Invalid JSON payload received. Unknown name "$schema" at 'generation_config.response_schema': Cannot find field.
Invalid JSON payload received. Unknown name "type" at 'generation_config.response_schema.properties[2].value': Proto field is not repeating, cannot start list.

Test plan

  • Added unit tests for $schema stripping
  • Added unit tests for array type → nullable conversion
  • All existing tests pass

🤖 Generated with Claude Code

Fixes 400 errors on Gemini requests with structured output:
- Strip $schema field from JSON schemas (Gemini doesn't recognize it)
- Convert array types like ["string", "null"] to type: "string" + nullable: true

Addresses errors:
- "Unknown name '$schema' at 'generation_config.response_schema'"
- "Unknown name 'type' at '...': Proto field is not repeating, cannot start list"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Feb 18, 2026

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

Project Deployment Actions Updated (UTC)
helicone Ready Ready Preview, Comment Feb 18, 2026 9:06pm
helicone-bifrost Ready Ready Preview, Comment Feb 18, 2026 9:06pm
helicone-eu Ready Ready Preview, Comment Feb 18, 2026 9:06pm

Request Review

@supabase
Copy link

supabase bot commented Feb 18, 2026

This pull request has been ignored for the connected project bolqqmqbrciybnypvklh because there are no changes detected in supbase/supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@supabase
Copy link

supabase bot commented Feb 18, 2026

This pull request has been ignored for the connected project lmahfbbnchpworytrrqk because there are no changes detected in .supabase/supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@claude
Copy link
Contributor

claude bot commented Feb 18, 2026

Claude finished @colegottdank's task —— View job


Code Review: Gemini Schema Conversion Fixes

Score: 8/10 - Well-implemented fix with good test coverage, ready to merge with minor suggestions

Analysis

This PR effectively addresses the 400 errors from Gemini's API by implementing proper schema transformation. The implementation correctly handles two key issues:

  1. $schema field stripping: Gemini doesn't recognize JSON Schema version identifiers
  2. Array type conversion: Transforms OpenAI's ["string", "null"] format to Gemini's type: "string", nullable: true

Strengths

Comprehensive test coverage - Tests cover all transformation scenarios including edge cases
Recursive implementation - Properly handles nested schemas, arrays, and combinators (allOf, anyOf, oneOf)
Maintains schema integrity - Preserves all valid schema properties while cleaning problematic ones
Real-world scenarios - Includes Vercel AI SDK test case showing practical usage

Code Quality Assessment

Implementation (toGoogle.ts:360-440):

  • Clean recursive function with proper type safety
  • Handles complex nested structures correctly
  • Good error handling for edge cases (null-only types, multiple non-null types)

Tests (openai-to-google-response-format.test.ts):

  • Comprehensive coverage of transformation scenarios
  • Clear test descriptions and assertions
  • Good use of realistic examples

Minor Suggestions

  1. Edge case handling in stripOpenAISchemaFields:390-394:

    } else if (hasNull && nonNullTypes.length === 0) {
      // Only null type - shouldn't happen but handle gracefully
      cleaned.type = "string";
      cleaned.nullable = true;
    }

    Consider logging a warning for this edge case to help with debugging.

  2. Type safety improvement: The function parameter could be more strictly typed:

    // Current
    function stripOpenAISchemaFields(schema: Record<string, any> | undefined)
    
    // Suggestion
    function stripOpenAISchemaFields(schema: JSONSchema | undefined)
  3. Performance consideration: For deeply nested schemas, consider adding a depth limit to prevent stack overflow.

Security & Performance

No security concerns - Pure transformation function with no external dependencies
Performance appropriate - Recursive approach suitable for typical schema sizes
No breaking changes - Maintains backward compatibility

Verification

The test cases demonstrate the fix addresses the exact errors mentioned:

  • "Unknown name "$schema" → Fixed by delete cleaned.$schema
  • "Proto field is not repeating, cannot start list" → Fixed by array type conversion

Ready to merge - This implementation properly fixes the Gemini API compatibility issues while maintaining robust error handling and test coverage.

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.

1 participant