Skip to content

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

@svetanis

Description

@svetanis

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

The ADK framework's ChatCompletionsRequest serialization generates JSON payloads that violate strict OpenAI/Groq requirements. Specifically, it maps empty arguments maps and empty function response objects to null or omits them entirely, which causes the downstream API to drop the context and hallucinate.

Please make sure you read the contribution guide and file the issues in the right place.
Contribution guide.

🔴 Required Information

Describe the Bug:
When using third-party OpenAI-compatible providers like Groq, multi-turn tool calling fails. If an agent executes a tool that requires 0 arguments (like getCurrentTime), the ADK serializes the assistant's message with arguments: null or omits the arguments field. Furthermore, during tool declaration, it omits the parameters schema object entirely for zero-argument functions. Strict parsers (like Groq) reject or silently drop this malformed tool history, leading the model to lose context. Consequently, the model hallucinates raw XML-like tool calls, causing a fatal 400 Bad Request error. Additionally, JSON Schema enum types for tools are incorrectly serialized in uppercase (e.g., "STRING" instead of "string").

Steps to Reproduce:

  1. Configure an ADK agent with multiple tools (e.g., getCurrentTime, getWeather).
  2. Set the model provider to groq/llama-3.3-70b-versatile.
  3. Send a prompt that requires executing a tool with no arguments.
  4. The first tool executes, but the subsequent request to the model crashes with a 400 Bad Request.

Expected Behavior:
The ADK ChatCompletionsRequest should strictly comply with the OpenAI JSON specifications:

  • arguments must be a non-null JSON string (e.g., "{}" if empty).
  • content for tool roles must be a non-null string (e.g., "{}" if empty).
  • parameters schema objects must exist in function declarations, even for zero-argument functions (e.g., {"type":"object", "properties":{}}).
  • JSON Schema Type enums must be serialized in lowercase.

Observed Behavior:
The framework throws a 400 Bad Request exception due to model hallucinations caused by dropped context:

Exception in thread "main" java.lang.RuntimeException: java.io.IOException: HTTP request failed with status: Response{protocol=h2, code=400, message=, url=https://api.groq.com/openai/v1/chat/completions} - body: {"error":{"message":"tool call validation failed: attempted to call tool 'brave_search' which was not in request.tools","type":"invalid_request_error","code":"tool_use_failed","failed_generation":"<function=brave_search>{\"query\":\"HACK stock price\"}</function>"}}

Environment Details:

  • ADK Library Version: 1.4.1-SNAPSHOT
  • OS: Windows (also reproducible on macOS/Linux)
  • TS Version: N/A

Model Information:

  • Which model is being used: groq/llama-3.3-70b-versatile

🟡 Optional Information

How often has this issue occurred?:

  • Always (100%)

Metadata

Metadata

Assignees

Type

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions