googleapis / googleapis/python-genai
[Batch API] Remote MCP (tools.mcp_servers) + structured output → every row fails code: 3 INVALID_ARGUMENT, yet job reports BATCH_STATE_SUCCEEDED
- Dominant language
- Python
- Stars
- 4k
- Forks
- 1k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 40
Description
# [Batch API] Remote MCP (`tools.mcp_servers`) + structured output → every row fails `code: 3 INVALID_ARGUMENT`, yet job reports `BATCH_STATE_SUCCEEDED`
### Description
In **Batch mode**, a request combining a **remote MCP server** (`tools.mcp_servers`) with a
**structured-output directive** (`response_mime_type: "application/json"` + `response_json_schema`,
or `response_schema`) is accepted, runs, and finishes as **`BATCH_STATE_SUCCEEDED`** — but **every
request inside fails** with `code: 3, "Request contains an invalid argument."`
(`failedRequestCount == requestCount`). No error at submission; you only find out after downloading
the responses. Dropping the structured-output directive makes the same MCP request succeed, so the
input shape is valid — it's the `mcp_servers` + structured-output combination.
### Environment
- google-genai 2.8.0 · Python 3.11.12 · macOS 15
- Gemini Developer API, `models/{model}:batchGenerateContent` — reproduced on **both `v1beta` and `v1alpha`**
- Model `gemini-3-flash-preview` (also 2.5-flash/pro, 3.5-flash, 3.1-pro-preview)
### Input (one batch request line)
```json
{"request": {"contents": [{"role": "user", "parts": [{"text": "Find Apple's HQ city; answer JSON {hq}."}]}], "tools": [{"mcp_servers": [{"name": "web", "streamable_http_transport": {"url": "https:///mcp/web", "headers": {"x-api-key": ""}}}]}], "generationConfig": {"responseMimeType": "application/json", "responseJsonSchema": {"type": "object", "properties": {"hq": {"type": "string"}}, "required": ["hq"]}}}}
```
Submitted via `POST /v1beta/models/gemini-3-flash-preview:batchGenerateContent` with body
`{"batch": {"inputConfig": {"requests": {"requests": [ , ... ]}}}}`.
### Actual output (real batch result)
```json
{
"metadata": {
"state": "BATCH_STATE_SUCCEEDED",
"batchStats": { "requestCount": "2", "failedRequestCount": "2" },
"output": { "inlinedResponses": { "inlinedResponses": [
{ "error": { "code": 3, "message": "Request contains an invalid argument." } },
{ "error": { "code": 3, "message": "Request contains an invalid argument." } }
]}}
},
"done": true
}
```
(On gemini-2.5 the message is explicit: `"Function calling with a response mime type:
'application/json' is unsupported"`. Changing the MIME type — xml/yaml/enum — doesn't help; only
`text/plain`/no-schema is accepted.)
### Expected
Either return schema-valid JSON per row, **or** reject at submission with a clear message, **and**
do not report `BATCH_STATE_SUCCEEDED` when `failedRequestCount == requestCount`.
Contributor guide
Assessment
This issue has not been assessed yet.