Gemini INVALID_ARGUMENT: meaning, cause, and fix

Google's catch-all 400 is usually a version mismatch wearing a typo costume. The message names the symptom, never the field.

By the benchr team · · Verified against Google's Gemini API troubleshooting docs, June 12, 2026

Google GeminiHTTP 400severity: mediumrequest format

Malformed, or just mismatched

Two failure families share this status. The first is the boring one: a typo in a field name, a required field left out, a string where a number belongs. You'll find these by reading your payload against the reference docs, slowly, the way you'd proofread a contract.

The second family is sneakier, and it's the one that eats afternoons. The body is perfectly legal — on a different API version. Google ships new capabilities to v1beta before v1, so a feature copied from one doc page can be unknown to the endpoint another doc page told you to call. Mixed SDK examples, copied snippets, and an unpinned default version blend into a request that's valid everywhere except where you sent it.

The response

A representative body, in the standard Google envelope where the numeric code repeats the HTTP status and status holds the gRPC name:

{
  "error": {
    "code": 400,
    "message": "The request body is malformed.",
    "status": "INVALID_ARGUMENT"
  }
}

Exact wording differs by failure, and the message rarely names the guilty field. That silence is why the rebuild method below beats staring at logs.

Rebuild from minimal

Prove the plumbing first. The smallest valid generateContent call puts the model in the URL path and sends one contents entry:

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.5-flash:generateContent" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [
      { "parts": [ { "text": "Say hello." } ] }
    ]
  }'

If this passes, your schema drifted somewhere above it: add your real fields back one at a time and the 400 will reappear on the exact addition that breaks. If even the minimal call fails, suspect the URL before the body — the model name and the version segment cause more of these than any payload does.

Pin your versions

Three habits make this error rare. Put the API version in the URL explicitly and treat it as config, so every environment provably calls the same endpoint. Validate payloads against a schema before sending; a small JSON Schema check in CI catches drifting field names years before a user does. And when you move between model lines, reread the release notes instead of trusting that the request shape carried over — fields appear, rename, and change types across generations. If a switch to Gemini 3.1 Pro is what surfaced the error, the tracker shows what else changed around the model you just adopted.

Frequently asked

The same code works in one project and 400s in another. Why?

The two projects are almost certainly calling different API versions, or one depends on a feature that only exists on v1beta. Print the full request URL from both environments and compare the version segment before touching the payload.

Which API version should I call?

The one whose documentation describes the feature you need, pinned explicitly in the URL. Letting an SDK default pick for you is how the mismatch sneaks in.

Is INVALID_ARGUMENT ever a server-side problem?

Rarely. Treat it as a client problem until a minimal request fails too. Server trouble tends to surface as 500 INTERNAL or 503 UNAVAILABLE, and oversized input context is the usual 500 trigger.

Changelog

  • — Published. Malformed-body semantics, version-mismatch cause, and error envelope verified against Google's Gemini API troubleshooting guide.

Sources

  • Gemini API troubleshooting: ai.google.dev/gemini-api/docs/troubleshooting (verified June 12, 2026)
  • benchr api-errors.json (structured entry for this error)