Short Answer
When Gemini 3 and later models (gemini-4-argon, gemini-3.8-flash, gemini-3.1-pro-preview, and so on) run multi-turn function calling, there are two kinds of 400 errors related to the thought signature (thoughtSignature), and they need different fixes:
/v1/chat/completions endpoint, none of this applies to you: the gateway manages signatures, and standard tool_calls / tool messages are all you need.
Telling the Two Errors Apart
Missing signature
parts array. This is a hard rule enforced by the model provider for the Gemini 3 family: every functionCall part in the current turn must carry its signature. A missing one fails with 400 on every route, and retrying does not help.
Invalid or corrupted signature
Why This Happens
When tools are enabled, Gemini 3 models attach an encryptedthoughtSignature to the same part as each functionCall, recording the reasoning state at that step. On the next request the model needs it to continue the reasoning chain, so the provider requires it to be sent back unchanged.
Missing: the client rebuilt the part
name and args of the functionCall when assembling history and drops the sibling thoughtSignature; or streaming chunks are reassembled without merging the signature in.Missing: history was compressed or rewritten
Invalid: route changed mid-conversation
Invalid: model changed mid-conversation
functionCall part; the others legitimately have none, so do not fabricate one. For sequential calls (several steps within one turn) every step carries a signature and every one must be returned.Fix 1: Missing Signature, Change How the Client Replays History
Put the whole model reply back verbatim
google-genai SDK, simply contents.append(response.candidates[0].content); do not extract only the function_call field. In hand-written REST, the model turn in the second request’s contents must look like this:thoughtSignature and functionCall are two fields of the same part, not two parts.Check whether a framework or middleware strips the field
thoughtSignature is still there. The position N in the error is parts[N]; look there directly.Do not rely on some models letting it through
Fix 2: Invalid Signature, Resend or Start Over
Resend once as is
Still 400: strip signatures from history turns and resend
thoughtSignature field from the parts of every role: "model" turn in the history, then resend. You lose the reasoning context of those turns and answer quality may dip slightly, but the conversation can continue. Only strip history turns, never the current one.Or start a new conversation
One model, one key per conversation
No Signature Handling on the OpenAI-Compatible Endpoint
When you call Gemini through/v1/chat/completions, tool_calls messages have no signature field; the gateway saves and restores it during translation. In our tests on gemini-4-argon, two-turn conversations passed for all three shapes: a single call, two parallel calls, and text plus a call. Just return tool_calls and tool messages the standard OpenAI way.
/v1/responses need to switch to the chat protocol, since Gemini models do not support that endpoint yet. See Gemini 4 Argon Text Generation.FAQ
Only argon throws this; flash has always been fine. Is argon broken?
Only argon throws this; flash has always been fine. Is argon broken?
Can I cache a signature and reuse it across conversations?
Can I cache a signature and reuse it across conversations?
Where is the signature in a streaming response?
Where is the signature in a streaming response?
functionCall, inside the chunk that carries it. When reassembling the stream, merge this field together with functionCall into the final model reply before putting it back into history.Do plain-text turns need signatures too?
Do plain-text turns need signatures too?
functionCall parts; a missing signature on a text turn does not 400, but keeping it helps reasoning continuity, so return the whole reply verbatim anyway.