openclaw - ✅(Solved) Fix Vertex AI Gemini function calls fail with 'Function call is missing a thought_signature in functionCall parts' [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#63397Fetched 2026-04-09 07:54:15
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Author
Participants

When OpenClaw routes a tool-using request through LiteLLM to Vertex AI Gemini (gemini-flash, gemini-2.x, etc.), Vertex returns HTTP 400 with the error message Function call is missing a thought_signature in functionCall parts. This is required for tools to work correctly, and missing thought_signature may lead to degraded model performance. The function call payload OpenClaw constructs for Vertex/Gemini doesn't include the thought_signature field that Vertex's beta API now requires for tool use.

The error surfaces immediately on any agent run that:

  1. Has tool definitions registered (built-in OR MCP)
  2. Falls through to a Gemini model in the fallback chain

Error Message

FailoverError: HTTP 400: litellm.BadRequestError: Vertex_ai_betaException BadRequestError - b'{ "error": { "code": 400, "message": "Function call is missing a thought_signature in functionCall parts. This is required for tools to work correctly, and missing thought_signature may lead to degraded model performance. Additional data, function call default_api:ms365__list-calendar-events, position 37. Please refer to https://ai.google.dev/gemini-api/docs/thought-signatures for more details.", "status": "INVALID_ARGUMENT" } }'

Root Cause

When OpenClaw routes a tool-using request through LiteLLM to Vertex AI Gemini (gemini-flash, gemini-2.x, etc.), Vertex returns HTTP 400 with the error message Function call is missing a thought_signature in functionCall parts. This is required for tools to work correctly, and missing thought_signature may lead to degraded model performance. The function call payload OpenClaw constructs for Vertex/Gemini doesn't include the thought_signature field that Vertex's beta API now requires for tool use.

The error surfaces immediately on any agent run that:

  1. Has tool definitions registered (built-in OR MCP)
  2. Falls through to a Gemini model in the fallback chain

Fix Action

Workaround

Remove gemini-flash (and any other Gemini variant) from any LiteLLM fallback chain that may include tool-using models:

router_settings:
  fallbacks:
    - claude-haiku-4-5: [claude-sonnet-4-6]   # was: [claude-sonnet-4-6, gemini-flash]
    - routellm-auto: [gpt-5-mini]              # was: [gemini-flash, gpt-5-mini]

Gemini can still be used as a primary model for non-tool-using requests, but should not be reached via fallback for any agent that has tools enabled.

PR fix notes

PR #66949: agents/google: round-trip Gemini 3 thoughtSignature on tool calls to unblock Gemini 3.x tool-calling

Description (problem / solution / changelog)

Summary

Impact: enables Gemini 3.x for openclaw tool-calling. Without this, any tool-calling turn on gemini-3-flash-preview (or Gemini 3.1 Pro Preview) via openclaw's native google-generative-ai transport softlocks on turn two — the model emits a tool call, openclaw executes it, and the follow-up request 400s because the signature was dropped in transit.

  • Problem: src/agents/google-transport-stream.ts parses thoughtSignature off thinking/text parts but not off tool-call parts. Google rejects any subsequent request whose functionCall parts are missing the signature that was attached on the way in: Function call is missing a thought_signature in functionCall parts. ... function call <namespace>:<tool>, position N.
  • Why it matters: Gemini 3 is unusable for tool calling through openclaw today. Agents on gemini-3-flash-preview show typing indicators and never reply. This blocks any MCP integration or tool-catalog plugin that guarantees a tool-call turn.
  • What changed: Capture part.thoughtSignature at the tool-call construction site in the SSE parser, and plumb it through GoogleTransportContentBlock.toolCall so the existing serializer (which already re-emits signatures byte-exact on same-provider-and-model replay) has data to emit.
  • What did NOT change (scope boundary): Only the native google-generative-ai transport. The OpenAI-compat path (#53658, #58235) has a structurally equivalent bug and is intentionally not bundled here — separate PR, separate concern. Cross-model replay still strips thoughtSignature via the existing transport-message-transform.ts logic (unchanged and verified).

Change Type

  • Bug fix

Scope

  • Integrations
  • API / contracts

Linked Issue/PR

  • Closes #63397 (Vertex AI Gemini — native path, exact match)
  • Related #34008 (Gemini 3 via Ollama Cloud — same missing-signature symptom, different transport)
  • Related #53658 (Google OpenAI-compat fallback — parallel bug on the compat path, intentionally out of scope here)
  • Related #58235 (Gemini 3.1 Pro Preview via OpenAI-compat API — same, compat path)
  • Context #5001, #841 (prior thought-signature-related reports)
  • This PR fixes a bug or regression

Root Cause

  • Root cause: Parser/serializer asymmetry. The serializer at src/agents/google-transport-stream.ts:355 already emits thoughtSignature when present on a tool-call block under same-provider-and-model replay. The parser at src/agents/google-transport-stream.ts:709 constructed the tool-call block without reading part.thoughtSignature, so the field was never set and the serializer had nothing to emit. The SSE chunk type already declared the field as a sibling to functionCall, so the wire model was correct — only the in-memory content block lost it.
  • Missing detection / guardrail: No regression test exercised round-tripping a thoughtSignature on a tool-call part. Thinking-block signatures were covered; tool-call signatures were not.
  • Contributing context (if known): Gemini 3 was the first generation where the signature became mandatory on tool-call replay. Gemini 2.5 and earlier tolerated missing signatures, so the gap hid until Gemini 3 preview models started rejecting those requests.

Regression Test Plan

  • Coverage level that should have caught this:
    • Unit test
  • Target test or file: src/agents/google-transport-stream.test.ts
  • Scenario the test should lock in: byte-exact thoughtSignature round-trip on tool-call parts across same-provider replay; stripped on cross-provider replay; parallel-call first-only preservation; absence stays absent.
  • Why this is the smallest reliable guardrail: the bug is a one-field data-flow failure between parser and serializer. A provider-level unit test is the tightest surface that reproduces it without needing a live model.
  • Existing test that already covers this (if any): none for tool-call signatures specifically. The existing "uses the guarded fetch transport and parses Gemini SSE output" case covered thinking-block signatures but asserted nothing about tool-call parts.

Five new tests added in this PR:

  1. Parser captures thoughtSignature on tool-call SSE parts
  2. Serializer emits it byte-exact on same-provider replay
  3. Serializer omits the field when the tool call carried no signature
  4. Serializer strips the field when replaying across providers (regression guard for cross-model leakage)
  5. Parallel tool calls: signature preserved only on the parts that had one (mirrors Google's documented emission rule — only the first functionCall in a parallel batch carries a signature)

User-visible / Behavior Changes

None on the happy path for non-Gemini-3 users — the field is absent end-to-end for models that don't emit it, and same-provider replay for Gemini 2.5 and below is byte-identical. Gemini 3.x users gain working tool-calling where previously every multi-turn tool conversation failed.

Security Impact

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No (same endpoints; adds one optional field to the request body that Google itself produced on the prior response)
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: Linux x86_64, Node 22.22.1
  • Model/provider: gemini-3-flash-preview via google-generative-ai native transport
  • Integration/channel: any MCP server whose tool catalog guarantees a tool-call turn

Steps

  1. Configure an openclaw-driven agent on gemini-3-flash-preview with at least one tool plugin or MCP server.
  2. Send a query that routes through a tool.
  3. Observe the gateway emit two inference POSTs and zero outbound reply to the calling channel.

Expected

  • Agent replies. /v1beta/models/gemini-3-flash-preview:streamGenerateContent returns 200 on every turn of a multi-turn tool-calling conversation.

Actual (before fix)

  • Turn one succeeds (initial tool call). Turn two 400s with Function call is missing a thought_signature in functionCall parts. Please remove the thought signature from the previous Part.part at content[...] ... function call <namespace>:<tool>, position N. The agent never posts a reply.

Actual (after fix)

  • Both turns 200. Agent replies. Fetch-level 4xx/5xx capture stays empty across a multi-turn tool exchange.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets

Captured 400 response body before the fix (via a fetch-level preload):

Function call is missing a thought_signature in functionCall parts.
Please remove the thought signature from the previous Part.part at content[...].parts
function call <namespace>:<tool>, position 44

Test suite after the fix:

 Test Files  1 passed (1)
      Tests  10 passed (10)

Full src/agents/**/*.test.ts run: 365 files, 3799 passed, 4 skipped, 0 failed (144s).

End-to-end verified against a multi-tool-call conversation on gemini-3-flash-preview: every turn returned 200, the fetch-level error log stayed empty, and the agent completed the exchange normally.

Changed files

  • src/agents/google-transport-stream.test.ts (modified, +181/-0)
  • src/agents/google-transport-stream.ts (modified, +10/-1)
  • src/agents/openai-transport-stream.test.ts (modified, +247/-0)
  • src/agents/openai-transport-stream.ts (modified, +95/-0)

Code Example

model_list:
     - model_name: gemini-flash
       litellm_params:
         model: gemini/gemini-flash-latest
         api_key: os.environ/GEMINI_API_KEY

   router_settings:
     fallbacks:
       - claude-haiku-4-5: [claude-sonnet-4-6, gemini-flash]

---

FailoverError: HTTP 400: litellm.BadRequestError: Vertex_ai_betaException BadRequestError - b'{
     "error": {
       "code": 400,
       "message": "Function call is missing a thought_signature in functionCall parts. This is required for tools to work correctly, and missing thought_signature may lead to degraded model performance. Additional data, function call `default_api:ms365__list-calendar-events`, position 37. Please refer to https://ai.google.dev/gemini-api/docs/thought-signatures for more details.",
       "status": "INVALID_ARGUMENT"
     }
   }'

---

router_settings:
  fallbacks:
    - claude-haiku-4-5: [claude-sonnet-4-6]   # was: [claude-sonnet-4-6, gemini-flash]
    - routellm-auto: [gpt-5-mini]              # was: [gemini-flash, gpt-5-mini]
RAW_BUFFERClick to expand / collapse

Bug: Vertex AI Gemini function calls fail with Function call is missing a thought_signature in functionCall parts

Summary

When OpenClaw routes a tool-using request through LiteLLM to Vertex AI Gemini (gemini-flash, gemini-2.x, etc.), Vertex returns HTTP 400 with the error message Function call is missing a thought_signature in functionCall parts. This is required for tools to work correctly, and missing thought_signature may lead to degraded model performance. The function call payload OpenClaw constructs for Vertex/Gemini doesn't include the thought_signature field that Vertex's beta API now requires for tool use.

The error surfaces immediately on any agent run that:

  1. Has tool definitions registered (built-in OR MCP)
  2. Falls through to a Gemini model in the fallback chain

Environment

  • OpenClaw 2026.4.5 (3e72c03)
  • Ubuntu 24.04.4 LTS, Node v24.14.1 via nvm
  • LiteLLM proxy with Gemini configured via gemini-flash model alias
  • MCP server: @softeria/ms-365-mcp-server (110+ tool definitions, but the issue is general — happens with any tool-using request)

Steps to reproduce

  1. Configure a LiteLLM model entry for Gemini Flash and a fallback chain that points to it. Example:

    model_list:
      - model_name: gemini-flash
        litellm_params:
          model: gemini/gemini-flash-latest
          api_key: os.environ/GEMINI_API_KEY
    
    router_settings:
      fallbacks:
        - claude-haiku-4-5: [claude-sonnet-4-6, gemini-flash]
  2. Configure an OpenClaw agent that uses litellm/claude-haiku-4-5 and has access to any tool (built-in or MCP).

  3. Trigger an agent run that requires the agent to call a tool. (Easiest: register an MCP server with a tool the agent will plausibly use, then send a Teams/Signal/etc. message that triggers the tool call.)

  4. Force fallback to Gemini by either rate-limiting Anthropic temporarily, or by setting Gemini as the primary model directly.

  5. Observed: HTTP 400 from Vertex with the thought_signature error. Full error from our logs:

    FailoverError: HTTP 400: litellm.BadRequestError: Vertex_ai_betaException BadRequestError - b'{
      "error": {
        "code": 400,
        "message": "Function call is missing a thought_signature in functionCall parts. This is required for tools to work correctly, and missing thought_signature may lead to degraded model performance. Additional data, function call `default_api:ms365__list-calendar-events`, position 37. Please refer to https://ai.google.dev/gemini-api/docs/thought-signatures for more details.",
        "status": "INVALID_ARGUMENT"
      }
    }'

Expected behavior

OpenClaw's Gemini provider adapter (or the LiteLLM-passed payload) should include a thought_signature field in the functionCall parts of any request that includes tool definitions. The required format is documented at https://ai.google.dev/gemini-api/docs/thought-signatures.

Actual behavior

The function call payload OpenClaw constructs lacks the thought_signature field. Vertex returns HTTP 400. The agent run fails. With retries enabled in the fallback chain, the error compounds (multiple failed retries before giving up).

Severity

Medium-high. Anyone who lists Gemini in their LiteLLM fallback chain will hit this the moment a tool call routes through Gemini. For OpenClaw deployments using LiteLLM with mixed-provider fallback chains (a common pattern), this is a hidden trap that only surfaces when the primary provider fails.

Workaround

Remove gemini-flash (and any other Gemini variant) from any LiteLLM fallback chain that may include tool-using models:

router_settings:
  fallbacks:
    - claude-haiku-4-5: [claude-sonnet-4-6]   # was: [claude-sonnet-4-6, gemini-flash]
    - routellm-auto: [gpt-5-mini]              # was: [gemini-flash, gpt-5-mini]

Gemini can still be used as a primary model for non-tool-using requests, but should not be reached via fallback for any agent that has tools enabled.

Suggested fix paths

  1. Add thought_signature to the function call payload in OpenClaw's Gemini/Vertex provider adapter. The Vertex API docs at https://ai.google.dev/gemini-api/docs/thought-signatures specify the format.
  2. Detect Gemini in the LiteLLM target and either include the field automatically OR refuse to send tool-using requests to Gemini until support lands.
  3. Document the limitation in the OpenClaw docs page for litellm provider configuration so operators know to exclude Gemini from tool-using fallback chains.

Where this bit us

Synap deployment, 2026-04-08. We were wiring @softeria/ms-365-mcp-server to give pleres and family agents access to Microsoft 365 calendar/email/SharePoint. When Anthropic Haiku rate-limited under heavy testing, the LiteLLM fallback chain dispatched to Gemini, which returned the Vertex 400 on every tool call. Once removed from the fallback chain, the immediate issue went away — but Gemini is now effectively unusable for any tool-using request in this deployment until this is fixed.

Related upstream issues

  • #62763, #62764, #62765, #62766, #63357, #63394 (other OpenClaw issues filed during the same Synap deployment)

extent analysis

TL;DR

Add the thought_signature field to the function call payload in OpenClaw's Gemini/Vertex provider adapter to fix the HTTP 400 error.

Guidance

  • Identify the OpenClaw Gemini provider adapter and modify it to include the thought_signature field in the functionCall parts of any request that includes tool definitions.
  • Refer to the Vertex API documentation at https://ai.google.dev/gemini-api/docs/thought-signatures for the required format of the thought_signature field.
  • As a temporary workaround, remove Gemini from any LiteLLM fallback chain that may include tool-using models to prevent the error.
  • Consider detecting Gemini in the LiteLLM target and either including the thought_signature field automatically or refusing to send tool-using requests to Gemini until support lands.

Example

No code snippet is provided as the issue does not include the specific code that needs to be modified. However, the thought_signature field should be added to the function call payload in a format similar to the example in the Vertex API documentation.

Notes

The fix requires modifying the OpenClaw Gemini provider adapter, which may require updates to the OpenClaw codebase. Additionally, the workaround of removing Gemini from the LiteLLM fallback chain may not be suitable for all deployments.

Recommendation

Apply the workaround of removing Gemini from the LiteLLM fallback chain until the thought_signature field can be added to the function call payload. This will prevent the HTTP 400 error and allow tool-using requests to be processed correctly.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

OpenClaw's Gemini provider adapter (or the LiteLLM-passed payload) should include a thought_signature field in the functionCall parts of any request that includes tool definitions. The required format is documented at https://ai.google.dev/gemini-api/docs/thought-signatures.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING