Gemini 3 Pro returns 400 INVALID_ARGUMENT in Vercel AI SDK

I’m hitting a wall trying to run google/gemini-3-pro-preview with tools enabled through streamText + @openrouter/ai-sdk-provider. Curious if anyone has replicated this or found a workaround. I can see some posts on n8n community and other communities with this issue.

Stack

  • Node 20 backend with Vercel AI SDK (ai latest)

  • OpenRouter provider (@openrouter/ai-sdk-provider@1.7.5)

  • Streaming mode with 15 tool() definitions registered (toolChoice: ‘auto’)

  • Model: google/gemini-3-pro-preview (same code path works fine for GPT-4o, Claude, Gemini 2.5, etc.)

What happens

  1. Model issues a tool call normally (we log the entire result.fullStream, including custom “Gemini3 Debug” lines).

  2. Tool executes (in this case a GitHub REST fetch) and we send the tool-result back.

  3. Next streamText call to OpenRouter immediately fails before any new tokens arrive: Google responds with 400 INVALID_ARGUMENT, and finishReason is unknown.

Full error snippet:

{

“error”: {

*"code"*: 400,

*"message"*: "Provider returned error",

*"metadata"*: {

  *"raw"*: "{\\n  \\"error\\": {\\n    \\"code\\": 400,\\n    \\"message\\": \\"Request contains an invalid argument.\\",\\n    \\"status\\": \\"INVALID_ARGUMENT\\"\\n  }\\n}\\n",

  *"provider_name"*: "Google"

}

}

}

Suspected cause

Gemini 3’s docs say function/tool calls require a thought_signature token that must be echoed back alongside the tool response. Problem: the Vercel/OpenRouter stream never surfaces that field. My logs show the tool-call and tool-result data exactly, but there’s no signature to replay, so Google drops the conversation as soon as the next turn starts.

What I’ve tried

  • Added instrumentation around result.fullStream to dump any chunk with thought_signature/thoughtSignature. Got nothing.

  • Reduced context, removed attachments, etc.—same error.

  • Switching to “ask” mode within my platform (no tools) works fine, so the issue only appears when tools are available.

  • Reached out to OpenRouter support to ask if they expose thought signatures yet.

Questions for whoever is reading

  1. Has anyone successfully run Gemini 3 with tools via Vercel’s AI SDK (either directly or through OpenRouter)?

  2. Does the SDK expose thought_signature anywhere, and if so, how are you capturing/replaying it between steps?

  3. If it’s not supported yet, are folks disabling tools for Gemini 3 or routing those calls straight to Google’s API?

Happy to share more logs or a minimal repro. Appreciate any pointers!

1 Like

Having the same issue with the google vertex ai provider (not openrouter).

Exact same observation - follow up from first tool execution results in the same 400 error you provided. Insanely opaque error, super frustrating

I reached out to Openrouter for this. They said that it’s on their end and they’re actively looking to resolve it.

1 Like

Keep us updated on how things go! :slight_smile:

Hi there, just flagging that we are experiencing the same error with roughly the same implementation as OP:

  • Node 24 Next.js proxy running Vercel AI SDK v5 with streamText
  • OpenRouter provider
  • Streaming mode
  • Model: google/gemini-3-pro-preview (same code path works for Gemini 2.5)

Adding some more context to this thread, hopefully its helpful:

  1. making a direct call to OpenRouter for Gemini 3 from our backend we do receive a reasoning_details object which includes the encrypted reasoning, eg:
data: {"id":"gen-1763551424-randomstring","provider":"Google AI Studio","model":"google/gemini-3-pro-preview","object":"chat.completion.chunk","created":1763551425,"choices":[{"index":0,"delta":{"role":"assistant","content":"","reasoning":null,"reasoning_details":[{"type":"reasoning.encrypted","data":"EtcMCt...encrypted...IrLHU","format":"google-gemini-v1","index":0}]},"finish_reason":"stop","native_finish_reason":"STOP","logprobs":null}]}
  1. however, these^ values do not appear to be accessible once passed through to the Vercel AI SDK streamText or other interfaces - the providerMetadata params, onChunk callback, and other values associated with various parts of the streamText interface seem like they could hold this info for us to persist for serial model/tool calls within the same chat completion call, but logging those does not appear to show such values, instead only showing the decrypted reasoning text at most, eg:
onChunk chunk {
  "chunk": {
    "type": "reasoning-delta",
    "id": "gen-1764006050-randomstring",
    "text": "**Examining Data Limitations**\n\nI am now carefully considering the limitations imposed by the available tools. Specifically, the lack of complete historical data. My plan has shifted from generating a detailed lifetime chart to potentially displaying key metrics over time or identifying alternative data sources. This is a critical adjustment.\n\n\n"
  }
}

We’ve tried manually extracting the reasoning_details value and re-injecting it to the message stream after a successful tool call within a given response, but haven’t gotten it working quite right, and this feels like something that should be abstracted somewhere along the way by one or more of Gemini 3, OpenRouter provider, or the AI SDK interfaces, so I’m keeping an eye on this thread!

2 Likes

Hi @pawlean I am still experiencing the issue. Please may we get some help. It has been nearly a week and it is not resolved. Openrouter has not been helpful or responsive past the point of claiming they will get it fixed but it seems that they’re happy to have it fixed only on the Openrouter platform but not when being used in the Vercel AI SDK. I am not certain of what’s going on but I desperately need assistance.

@lcrawford-5564 Thank you for sharing that!

@calebsakala From my understanding, this is an Openrouter problem? What else did they say? :slight_smile:

In any case, I’ll flag this to the AI SDK team. Thank you!

1 Like

When making a direct call to Openrouter we see the reasoning_details field, but in the Vercel AI SDK, we do not. I think it is somewhere between the Vercel AI SDK and Openrouter - and this is so strange because every single model works fine except Gemini 3 Pro Preview. @lcrawford-5564 is right in that this feels like dealing with encrypted reasoning details feels like something which should be abstracted away on the SDK level. Openrouter seem to have sorted out their issue on their end when making requests directly to Openrouter, but when calling it from the Vercel AI SDK, it does not work.

3 Likes

running into the same exact thing right now as @calebsakala described

I’m seeing the same issue, even locally with GoogleGenerativeAIProvider (no OpenRouter involved). It doesn’t happen on every tool call — only on
the ones where the model messes up the function call structure. In those cases, the next turn fails with the 400 INVALID_ARGUMENT / missing
thought_signature error. The stream response stop directly

Hi all,

I communicated with OpenRouter about this issue and they have deployed a fix to preserve reasoning_details in the AI-SDK v5 OpenRouter provider between tool calls for G3P - you will need to update the OpenRouter provider package to at least v1.2.8 to include the fix. I have tested it and the fix is working for us in production.

This fix should work out of the box if you’re using the AI-SDK to hit the OpenRouter API directly, but if you are proxying requests from the AI-SDK through any custom backend logic before hitting OpenRouter then you may still need to ensure the reasoning_details are persisted through your backend operations and passed on to the OpenRouter API.

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.