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

Open
#2,693 3 comments 0 reactions 1 assignee Claimed by @Venkaiahbabuneelam View on GitHub
priority: p2 type: bug
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.