Since early 2026, Gemini has had multiple search grounding issues: the April 8 empty response bug with 2.0 Flash google_search, the March 3 image grounding regression, and Flash not triggering search reliably when external tools are registered. Gemini 3 Pro improved but is not immune. This tutorial adds a backup search layer using external APIs.
Prerequisites
- Gemini API access
- Scavio API key
- Optional: Tavily API key
- Python 3.8+
Walkthrough
Step 1: Detect Gemini search failure modes
Identify the specific failure patterns.
def detect_gemini_failure(response):
# Mode 1: No candidates at all
if not response.candidates:
return 'no_candidates'
candidate = response.candidates[0]
# Mode 2: No grounding metadata (search did not trigger)
grounding = getattr(candidate, 'grounding_metadata', None)
if not grounding:
return 'no_grounding'
# Mode 3: Empty grounding chunks (April 2026 bug)
if not grounding.grounding_chunks:
return 'empty_chunks'
# Mode 4: Grounding present but no search queries logged
if not grounding.search_entry_point:
return 'no_search_queries'
return None # Search workedStep 2: Build the backup search function
Call Scavio when Gemini fails. Tavily ($0.008/credit) also works as backup.
import requests, os
H = {'x-api-key': os.environ['SCAVIO_API_KEY']}
def backup_search(query, provider='scavio'):
if provider == 'scavio':
# $0.005 per search
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=H,
json={'platform': 'google', 'query': query}).json()
return data.get('organic_results', [])
elif provider == 'tavily':
# $0.008 per credit (Nebius-owned since Feb 2026)
data = requests.post('https://api.tavily.com/search',
json={'api_key': os.environ.get('TAVILY_API_KEY', ''),
'query': query}).json()
return data.get('results', [])Step 3: Integrate backup into Gemini workflow
Wrap your Gemini call with automatic backup.
import google.generativeai as genai
genai.configure(api_key=os.environ['GEMINI_API_KEY'])
model = genai.GenerativeModel('gemini-2.0-flash',
tools=[genai.Tool(google_search=genai.GoogleSearch())])
def gemini_with_backup(query):
response = model.generate_content(query)
failure = detect_gemini_failure(response)
if failure:
print(f'Gemini search failed: {failure}. Using backup.')
backup_results = backup_search(query)
# Re-query Gemini with search results injected
augmented = f'Based on these search results, answer: {query}\n\nResults: {backup_results}'
return model.generate_content(augmented)
return responseStep 4: Log failure rates for analysis
Track which failure modes occur most.
import json, datetime
failure_log = []
def log_failure(query, failure_mode, backup_provider):
entry = {'ts': datetime.datetime.now().isoformat(), 'query': query,
'failure_mode': failure_mode, 'backup': backup_provider}
with open('gemini_failures.jsonl', 'a') as f:
f.write(json.dumps(entry) + '\n')Python Example
import os, requests
import google.generativeai as genai
genai.configure(api_key=os.environ['GEMINI_API_KEY'])
model = genai.GenerativeModel('gemini-2.0-flash',
tools=[genai.Tool(google_search=genai.GoogleSearch())])
H = {'x-api-key': os.environ['SCAVIO_API_KEY']}
def search(query):
resp = model.generate_content(query)
g = getattr(resp.candidates[0], 'grounding_metadata', None) if resp.candidates else None
if not g or not g.grounding_chunks:
return requests.post('https://api.scavio.dev/api/v1/search',
headers=H, json={'platform': 'google', 'query': query}).json()
return respJavaScript Example
// When Gemini fails, fallback to Scavio:
const backup = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'},
body: JSON.stringify({platform: 'google', query: userQuery})
}).then(r => r.json());Expected Output
Gemini workflow with automatic backup search. Detects 4 failure modes (no candidates, no grounding, empty chunks, no search queries). Falls back to Scavio ($0.005) or Tavily ($0.008).