Symptoms
A manually reconstructed generateContent function-calling history can fail with 400 INVALID_ARGUMENT saying a later function call is missing thought_signature. The reported issue used Node.js, @google/genai v1.38.0, Vertex AI global, and gemini-3-flash-preview. Its opening report blamed provider signature omissions. The author later corrected that diagnosis, including a logging artifact that appeared to duplicate a signature.
Cause
For parallel calls in one model response, the official thought-signature guide places thought_signature on the first functionCall part only. The author had extracted each call and replayed it as a separate role: "model" Content. That made later calls look like first calls in new steps, where signature validation applies. The absence of a signature on subsequent parts of the same response is expected.
Safe resolution
Persist each model response as one Content with its complete ordered parts; replay that Content without moving, inventing, or copying signatures. Keep function responses associated with that same step in their returned order. The JSON below is a synthetic shape fixture, not a captured response or a usable signature:
{
"contents": [
{ "role": "user", "parts": [{ "text": "Check Paris and London weather." }] },
{ "role": "model", "parts": [
{ "functionCall": { "name": "weather", "args": { "city": "Paris" } }, "thoughtSignature": "SIGNATURE_FROM_THIS_RESPONSE" },
{ "functionCall": { "name": "weather", "args": { "city": "London" } } }
] },
{ "role": "user", "parts": [
{ "functionResponse": { "name": "weather", "response": { "city": "Paris", "tempC": 15 } } },
{ "functionResponse": { "name": "weather", "response": { "city": "London", "tempC": 12 } } }
] }
]
}
The placeholder must be replaced only by the exact signature returned on that first part. Do not merge calls from different sequential model responses. If storing calls separately, record their response identity and original part index so reconstruction can restore that same Content.
Verification
Source review on 2026-10-15 confirms the official parallel-call rule and the correction by the issue author; no Gemini API call or SDK fix-version test was performed. Compare a locally captured response with the next request: one model Content should contain the same number and order of functionCall parts, and the signature should remain on the original part only. As a negative control, a synthetic split into separate model Contents has the structural defect described by the author; do not submit fabricated signatures to the service. Local static checks can inspect structure but cannot prove a live 400 is resolved.
Limitations
This is a generateContent history diagnosis for the reported environment, not proof about every Gemini API, model, platform, or SDK release. The source review does not establish a particular SDK version that fixes custom history reconstruction. Built-in chat history may manage grouping, while custom serialization still needs inspection. No credentialed Vertex AI request was made.
Sources and verification scope
Source review on 2026-10-15 confirms the official parallel-call rule and the correction by the issue author; no Gemini API call or SDK fix-version test was performed.
- gemini-thought-doc (documentation) · checked:
- gemini-initial-issue (documentation) · checked:
- gemini-author-correction (code) · checked: