Skip to content

fix: Enforce strict JSON Schema compliance to prevent OpenAI 400 Bad Request errors#1266

Open
svetanis wants to merge 1 commit into
google:mainfrom
svetanis:fix-openai-json-schema-compliance
Open

fix: Enforce strict JSON Schema compliance to prevent OpenAI 400 Bad Request errors#1266
svetanis wants to merge 1 commit into
google:mainfrom
svetanis:fix-openai-json-schema-compliance

Conversation

@svetanis

Copy link
Copy Markdown

Enforce strict JSON Schema compliance to prevent OpenAI 400 Bad Request errors

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

2. Or, if no issue exists, describe the change:

Problem:
When using strict OpenAI-compatible providers like Groq, empty function arguments or responses are serialized as null or omitted by ChatCompletionsRequest. Furthermore, zero-argument tools fail to declare a parameters schema object. This breaks strict JSON schema parsers, causing them to drop conversation history, which leads to 400 Bad Request exceptions due to models hallucinating raw XML <function> tags. JSON Schema enum types are also improperly serialized in uppercase.

Solution:

  • Added a custom schemaNormalizerModule to the ObjectMapper in ChatCompletionsRequest.java to force Type enums to serialize in lowercase (e.g., "string").
  • Added enforceJsonObject to ChatCompletionsCommon.java to guarantee that empty arguments and function response payloads fallback to "{}" instead of null or raw strings.
  • Updated ChatCompletionsRequest.java to explicitly inject a {"type":"object", "properties":{}} parameters schema for zero-argument functions instead of omitting it.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

Passed: mvn test
Added testFromLlmRequest_withEmptyFunctionArguments to ChatCompletionsRequestTest.java to explicitly test "{}" serialization for zero-argument tools. Updated testFromLlmRequest_withFunctionResponse expectations.

Manual End-to-End (E2E) Tests:

Wired the Google native chat completion client into the external model-prism project (PR #1199). Ran the integration through all the demo tests covering all main ADK features. The applications successfully execute multi-turn multi-tool conversations using strict JSON schema endpoints without throwing 400 Bad Request due to context loss.

Checklist

  • I have read the CONTRIBUTING.md document.
  • My pull request contains a single commit.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

Additional context

This change unlocks robust support for the rapidly growing ecosystem of OpenAI-compatible endpoints that enforce strict JSON Schema validation.

@hemasekhar-p

Copy link
Copy Markdown
Contributor

Hi @svetanis, thank you for your contribution! We appreciate you taking the time to submit this pull request. I noticed that your changes are not covered by the current test cases and the test you included passes even without your changes. Could you please include the corresponding unit tests to verify your changes?

@hemasekhar-p hemasekhar-p self-assigned this Jun 15, 2026
@hemasekhar-p hemasekhar-p added the waiting on reporter Waiting for reaction by reporter. Failing that, maintainers will eventually closed it as stale. label Jun 15, 2026
@svetanis svetanis force-pushed the fix-openai-json-schema-compliance branch from 1f64496 to 7017e53 Compare June 15, 2026 23:46
@svetanis

Copy link
Copy Markdown
Author

Hello @hemasekhar-p ,

Thank you for the review and the feedback!

I've updated the PR and added three new dedicated unit tests in ChatCompletionsRequestTest that specifically target and verify the strict JSON Schema compliance fixes. The new tests ensure that:

  1. Missing function arguments are correctly serialized as empty objects ({}).
  2. Absent tool parameters are automatically populated with the required empty object schema.
  3. Gemini's uppercase schema types (like OBJECT and STRING) are safely normalized to lowercase to satisfy strict OpenAI API validation.

I have also successfully rebased the branch on top of the latest main to ensure there are no conflicts with the recent thoughtSignature updates. Everything is folded neatly into a single commit and all tests are passing locally.

Additionally, I ran comprehensive end-to-end testing on the rebased branch, and all of the demos (including a new one validating the thoughtSignature functionality) passed successfully.

Please let me know if there is anything else you need!

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

Labels

waiting on reporter Waiting for reaction by reporter. Failing that, maintainers will eventually closed it as stale.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tool calls fail with 400 Bad Request due to strict JSON Schema violations (OpenAI)

2 participants