litellm - ✅(Solved) Fix [Bug]: Vertex AI Gemini 2.5 Flash/Pro - "Multiple tools are supported only when they are all search tools" when using MCP/function tools alongside deployment-level search tools (regression from v1.81.0) [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

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
BerriAI/litellm#23337Fetched 2026-04-08 00:37:26
View on GitHub
Comments
0
Participants
1
Timeline
5
Reactions
0
Participants
Timeline (top)
labeled ×3cross-referenced ×1referenced ×1

Error Message

litellm.BadRequestError: Vertex_ai_betaException BadRequestError - b'{ "error": { "code": 400, "message": "Multiple tools are supported only when they are all search tools.", "status": "INVALID_ARGUMENT" } }'

Root Cause

Root cause: The _merge_tools_from_deployment function introduced in v1.82 merges tools from litellm_params in the deployment config with tools from the user request. This results in multiple separate Tool objects being sent to Vertex AI (search tools + function declaration tools), which violates Vertex AI Gemini's constraint that multiple tool objects are only allowed when they are all search tools.

Fix Action

Fixed

PR fix notes

PR #23717: fix(vertex_ai): drop search tools when mixed with function declarations

Description (problem / solution / changelog)

Relevant issues

Fixes #23337

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have Added testing in the tests/test_litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

Type

<!-- Select the type of Pull Request --> <!-- Keep only the necessary ones -->

🐛 Bug Fix

Changes

When _merge_tools_from_deployment() merges deployment-level search tools (e.g. enterpriseWebSearch, urlContext from config) with user-request function calling tools (e.g. from MCP), Vertex AI rejects the request with 400 error: "Multiple tools are supported only when they are all search tools."

Fix

In _map_function() (vertex_and_google_ai_studio_gemini.py), detect when both function declarations and search tools are present. When conflict is detected, drop search tools and keep function declarations, with a warning log.

Tests

  • Added 4 new tests covering mixed tool scenarios
  • Updated 2 existing tests to match new behavior

Changed files

  • litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py (modified, +33/-0)
  • tests/test_litellm/llms/vertex_ai/gemini/test_vertex_and_google_ai_studio_gemini.py (modified, +129/-38)

Code Example

model_list:
  - model_name: gemini-2.5-flash
    litellm_params:
      model: vertex_ai/gemini-2.5-flash
      vertex_project: your-project
      vertex_location: us-central1
      tools: [{"enterpriseWebSearch": {}}, {"urlContext": {}}]

---

import openai

client = openai.OpenAI(
    api_key="your-litellm-key",
    base_url="http://localhost:4000"
)

response = client.chat.completions.create(
    model="gemini-2.5-flash",
    messages=[{"role": "user", "content": "Search for something"}],
    tools=[
        {
            "type": "function",
            "function": {
                "name": "notion_search",
                "description": "Search Notion",
                "parameters": {"type": "object", "properties": {"query": {"type": "string"}}}
            }
        }
    ]
)

---

litellm.BadRequestError: Vertex_ai_betaException BadRequestError - b'{
"error": {
"code": 400,
"message": "Multiple tools are supported only when they are all search tools.",
"status": "INVALID_ARGUMENT"
}
}'
RAW_BUFFERClick to expand / collapse

Check for existing issues

  • I have searched the existing issues and checked that my issue is not a duplicate.

What happened?

When using Gemini 2.5 Flash or Gemini 2.5 Pro on Vertex AI with search tools defined in litellm_params (e.g. enterpriseWebSearch, urlContext) in the config, AND the user sends additional function calling tools (e.g. via MCP), LiteLLM v1.82.x throws a 400 BadRequestError:

"Multiple tools are supported only when they are all search tools."

This is a regression from v1.81.0 where the same configuration worked correctly.

Root cause: The _merge_tools_from_deployment function introduced in v1.82 merges tools from litellm_params in the deployment config with tools from the user request. This results in multiple separate Tool objects being sent to Vertex AI (search tools + function declaration tools), which violates Vertex AI Gemini's constraint that multiple tool objects are only allowed when they are all search tools.

What did you expect to happen?

Function calling tools (from MCP or user request) should work alongside deployment-level search tools defined in litellm_params, as they did in v1.81.0. LiteLLM should either:

  1. Not merge deployment-level search tools with request-level function declaration tools, OR
  2. Properly combine them into a single tool object that Vertex AI accepts

Steps to Reproduce

  1. Set up LiteLLM proxy config with Gemini 2.5 Flash on Vertex AI with search tools in litellm_params:
model_list:
  - model_name: gemini-2.5-flash
    litellm_params:
      model: vertex_ai/gemini-2.5-flash
      vertex_project: your-project
      vertex_location: us-central1
      tools: [{"enterpriseWebSearch": {}}, {"urlContext": {}}]
  1. Send a chat completion request with additional function calling tools (e.g. from MCP):
import openai

client = openai.OpenAI(
    api_key="your-litellm-key",
    base_url="http://localhost:4000"
)

response = client.chat.completions.create(
    model="gemini-2.5-flash",
    messages=[{"role": "user", "content": "Search for something"}],
    tools=[
        {
            "type": "function",
            "function": {
                "name": "notion_search",
                "description": "Search Notion",
                "parameters": {"type": "object", "properties": {"query": {"type": "string"}}}
            }
        }
    ]
)
  1. Observe 400 BadRequestError from Vertex AI: "Multiple tools are supported only when they are all search tools."

Relevant log output

litellm.BadRequestError: Vertex_ai_betaException BadRequestError - b'{
"error": {
"code": 400,
"message": "Multiple tools are supported only when they are all search tools.",
"status": "INVALID_ARGUMENT"
}
}'

What part of LiteLLM is this about?

Proxy

What LiteLLM version are you on ?

v1.82.rc.3 (regression from v1.81.0)

Twitter / LinkedIn details

No response

extent analysis

Fix Plan

To resolve the issue, we need to modify the _merge_tools_from_deployment function to properly combine deployment-level search tools with request-level function declaration tools into a single tool object that Vertex AI accepts.

Here are the steps:

  • Modify the _merge_tools_from_deployment function to check if the tools from the deployment config and the user request are both search tools or function declaration tools.
  • If they are the same type, merge them into a single list of tools.
  • If they are different types, create a new tool object that combines the search tools and function declaration tools.

Example code:

def _merge_tools_from_deployment(deployment_tools, request_tools):
    # Check if deployment tools and request tools are both search tools or function declaration tools
    if all(tool.get('type') == 'search' for tool in deployment_tools) and all(tool.get('type') == 'search' for tool in request_tools):
        # Merge search tools
        merged_tools = deployment_tools + request_tools
    elif all(tool.get('type') == 'function' for tool in deployment_tools) and all(tool.get('type') == 'function' for tool in request_tools):
        # Merge function declaration tools
        merged_tools = deployment_tools + request_tools
    else:
        # Combine search tools and function declaration tools into a single tool object
        merged_tools = []
        search_tools = [tool for tool in deployment_tools + request_tools if tool.get('type') == 'search']
        function_tools = [tool for tool in deployment_tools + request_tools if tool.get('type') == 'function']
        merged_tools.append({'type': 'search', 'tools': search_tools})
        merged_tools.extend(function_tools)
    return merged_tools

Verification

To verify the fix, send a chat completion request with additional function calling tools and check that the response does not contain a 400 BadRequestError.

Example test code:

import openai

client = openai.OpenAI(
    api_key="your-litellm-key",
    base_url="http://localhost:4000"
)

response = client.chat.completions.create(
    model="gemini-2.5-flash",
    messages=[{"role": "user", "content": "Search for something"}],
    tools=[
        {
            "type": "function",
            "function": {
                "name": "notion_search",
                "description": "Search Notion",
                "parameters": {"type": "object", "properties": {"query": {"type": "string"}}}
            }
        }
    ]
)

if response.status_code == 200:
    print("Fix verified successfully")
else:
    print("Fix verification failed")

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING