ash-project / ash-project/ash_ai

Gemini API compatibility issue: Function calling JSON schema generation fails with 400 INVALID_ARGUMENT (Proto field is not repeating)

Open
#209 1 comment 0 reactions 0 assignees View on GitHub
bug
Dominant language
Elixir
Stars
189
Forks
89
Avg merge
8h 32m
Merged PRs (30d)
3

Description

### Code of Conduct

- [x] I agree to follow this project's Code of Conduct

### AI Policy

- [x] I agree to follow this project's AI Policy, or I agree that AI was not used while creating this issue.

### Versions

* Elixir version: 1.19.5
* Erlang/OTP version: 28 [erts-16.1]
* ash_ai version: 0.7.2
* req_llm version: 1.17.0
* LLM Model: Gemini (e.g., gemini-3.1-flash-lite / gemini-2.5-flash)

### Operating system

macOS

### Current Behavior

When the AI attempts to use a registered tool mapped to a typical Ash Read action (e.g., listing resources or fetching history), the API returns a 400 INVALID_ARGUMENT error due to invalid JSON schema structure.

When using ash_ai with the Gemini adapter (via req_llm), the automatic tool generation for Ash Read Actions fails. Gemini's API rejects the generated JSON schema because it contains nested structures or array-wrapped types for properties that Gemini expects to be flat scalar types or objects.
This happens because Gemini enforces a strict subset of OpenAPI 3.0 for its function calling parameters, and the translation from Ash Action arguments/metadata to JSON schema produces schemas that OpenAI accepts but Gemini strictly rejects.

### Error Logs:

```text
[warning] Metadata collection failed: %ReqLLM.Error.API.Request{
reason: "Invalid JSON payload received. Unknown name \"type\" at 'tools[0].function_declarations[0].parameters.properties[0].value': Proto field is not repeating, cannot start list.",
status: 400,
response_body: %{
"code" => 400,
"details" => [
%{
"@type" => "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations" => [
%{"description" => "Invalid JSON payload received. Unknown name \"type\" at 'tools[0].function_declarations[0].parameters.properties[0].value': Proto field is not repeating, cannot start list.", "field" => "tools[0].function_declarations[0].parameters.properties[0].value"}
]
}
],
"message" => "Invalid JSON payload received. Unknown name \"type\" at 'tools[0].function_declarations[0].parameters.properties[0].value': Proto field is not repeating, cannot start list.",
"status" => "INVALID_ARGUMENT"
}
}

** (Ash.Error.Unknown)
Bread Crumbs:
> Exception raised in: Draco.Chat.Message.respond
Api Error
* Stream failed: %ReqLLM.Error.API.Request{...}
(ash_ai 0.7.2) lib/ash_ai/tool_loop.ex:143: AshAi.ToolLoop.stream_iteration/1
(ash_ai 0.7.2) lib/ash_ai/tool_loop.ex:104: AshAi.ToolLoop.next_stream_chunk/1

```

### Reproduction

_No response_

### Expected Behavior

`ash_ai` should detect the adapter type or generate a Gemini-compatible strict OpenAPI 3.0 schema for registered tools, allowing the AI to successfully invoke standard Ash Read actions without payload validation errors.

Contributor guide

Open the contributing guide

Research direction

Start at lib/ash_ai/tool_loop.ex:104 and :143, then trace how registered Ash Read actions become tool schemas through the Gemini adapter. Reproduce with the listed Elixir, ash_ai, req_llm, and Gemini versions and inspect the generated schema against the reported API error. Done means standard Ash Read tools are accepted by Gemini, with coverage for the failing schema case.

Written by the indexing model from the issue text.

Assessment

Tech stack
elixir
Domain
ai, api
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.