◉GEMINI LABJP
●ARGON — gemini-4-argon is generally available as of 10/13, aimed at complex coding, agents, math and science●DEEP RES — deep-research-pro-preview-12-2025 shuts down 10/23, 6 days left. Move to deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 is GA (10/06). gemini-3.1-flash-image is deprecated with no shutdown date yet●MCP — One write-up cut an 85,000-token tool result to 310 tokens by wrapping it in an ADK FunctionTool●FLASH — gemini-3.7-flash and 3.5-flash now route automatically to newer Flash models (10/08)●NEW — Stop Re-Reading Every Crash Report: Gre…●ARGON — gemini-4-argon is generally available as of 10/13, aimed at complex coding, agents, math and science●DEEP RES — deep-research-pro-preview-12-2025 shuts down 10/23, 6 days left. Move to deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 is GA (10/06). gemini-3.1-flash-image is deprecated with no shutdown date yet●MCP — One write-up cut an 85,000-token tool result to 310 tokens by wrapping it in an ADK FunctionTool●FLASH — gemini-3.7-flash and 3.5-flash now route automatically to newer Flash models (10/08)●NEW — Stop Re-Reading Every Crash Report: Gre…
Articles/API / SDK
◈ API / SDK/2026-05-05Intermediate

When Gemini API Output Seems Wrong: 7 Common Causes and a Diagnostic Checklist

When Gemini API returns unexpected output — empty responses, wrong language, broken JSON, or Thinking content leaking into answers — here are 7 common causes with a practical diagnostic checklist and code examples.

Gemini API249troubleshooting87debugging4finish_reasontemperature4structured output9thinking7

You call the Gemini API and something feels off. The response is empty, cut short, in the wrong language, or just inconsistent. No error code, no stack trace — just output that doesn't match what you expected.

This is actually one of the harder debugging scenarios because there's no obvious failure signal. I've run into each of these patterns while building Gemini-powered applications, and this checklist covers the seven most common causes I see developers encounter.

1. Empty or Truncated Output

The first thing to check is finish_reason. Every Gemini API response includes a reason why generation stopped, and this single field often reveals the root cause immediately.

import google.generativeai as genai
 
genai.configure(api_key="YOUR_API_KEY")
response = genai.GenerativeModel("gemini-2.5-pro").generate_content("Hello, test input")
 
for candidate in response.candidates:
    print(f"finish_reason: {candidate.finish_reason}")
    text = candidate.content.parts[0].text if candidate.content.parts else "(empty)"
    print(f"content preview: {text[:200]}")

Common finish_reason values and what they mean:

  • STOP — Normal completion (this is what you want)
  • MAX_TOKENS — Hit the max_output_tokens limit mid-generation
  • SAFETY — Blocked by safety filters (covered below)
  • RECITATION — Stopped due to potential copyright content
  • OTHER — Miscellaneous reasons

If you're seeing MAX_TOKENS, add an explicit max_output_tokens to your generation_config or increase the existing value. The default can be surprisingly small for longer generation tasks.

2. Responding in the Wrong Language

Gemini generally tries to match the language of the input, but with technical prompts containing many English keywords, it can default to English even when your user intent is another language.

The most reliable fix is an explicit language instruction in your system prompt:

model = genai.GenerativeModel(
    model_name="gemini-2.5-pro",
    system_instruction=(
        "You are an assistant that always responds in Japanese. "
        "Regardless of the language of the user's input, always reply in Japanese. "
        "Never respond in English."
    )
)
 
response = model.generate_content("What is machine learning?")
print(response.text)  # Returns a Japanese response

This pattern is especially useful when building apps where the UI language should always match the user's locale, regardless of what technical terms appear in the prompt.

3. Broken JSON or Schema Mismatch

Asking Gemini to "respond in JSON format" via the prompt alone is unreliable. The model often wraps the JSON in a Markdown code block (```json ... ```), which breaks direct parsing. Use response_mime_type and response_schema instead:

import typing_extensions as typing
import json
 
class ArticleSummary(typing.TypedDict):
    title: str
    summary: str
    tags: list[str]
 
model = genai.GenerativeModel("gemini-2.5-pro")
result = model.generate_content(
    "Summarize the following article: [article text here]",
    generation_config=genai.GenerationConfig(
        response_mime_type="application/json",
        response_schema=ArticleSummary,
    ),
)
 
# Returns clean JSON without Markdown fencing
data = json.loads(result.text)
print(data["title"])   # str
print(data["tags"])    # list[str]

With response_mime_type="application/json", the model returns raw JSON with no code block wrapping. The schema enforcement also catches type mismatches before they reach your application logic.

4. Inconsistent Output on Repeated Calls

If you're getting wildly different results on the same input — especially for classification tasks, data extraction, or anything that needs to be deterministic — temperature is almost certainly the culprit.

response = model.generate_content(
    "Classify the sentiment of this review as: positive, negative, or neutral.",
    generation_config=genai.GenerationConfig(
        temperature=0.0,  # Push toward deterministic output
    ),
)
print(response.text)

temperature=0.0 doesn't guarantee identical output every time, but in practice it produces very consistent results. For translation, classification, extraction, and similar tasks, I keep temperature at 0.0–0.3. For creative writing or brainstorming, 0.7–1.0 makes more sense.

5. Thinking Content Leaking Into the Response

Gemini 2.5 and later models support a "Thinking" mode where the model reasons internally before responding. Depending on how you parse the response, this thinking content can appear mixed in with the final answer.

Thinking content is stored in parts with thought=True — you need to explicitly separate them:

response = model.generate_content(
    "What is 2 to the power of 10?",
    generation_config=genai.GenerationConfig(
        thinking_config={"thinking_budget": 1024}
    )
)
 
for part in response.candidates[0].content.parts:
    if hasattr(part, "thought") and part.thought:
        print(f"[thinking] {part.text[:80]}...")  # Log separately
    else:
        print(f"[answer] {part.text}")  # This is what users see

To disable Thinking entirely (for cost or latency reasons), set thinking_budget=0. Just be aware that for complex reasoning tasks, answer quality may drop noticeably.

6. Responses Blocked by Safety Filters

A finish_reason of SAFETY means one or more harm category filters triggered. Check safety_ratings to see exactly which category caused the block:

response = model.generate_content("your input text")
 
candidate = response.candidates[0]
if candidate.finish_reason.name == "SAFETY":
    print("Blocked by safety filters")
    for rating in candidate.safety_ratings:
        if rating.probability.name != "NEGLIGIBLE":
            print(f"  {rating.category.name}: {rating.probability.name}")

Before adjusting safety_settings thresholds, try providing context in the system instruction. Describing the use case clearly — "This is a medical information tool for healthcare professionals" or "This is a security research assistant" — often resolves false positives without needing to lower the safety thresholds. Always review the API terms of service before using BLOCK_NONE.

7. Quality That Seems Worse Than Before

If you're using dynamic model aliases like latest or flash-latest, a Google-side model update can silently change behavior in your application without any code changes on your end.

# Risky in production: version can change without notice
model = genai.GenerativeModel("gemini-2.5-pro-latest")
 
# Safer for production: pin to a specific version string
model = genai.GenerativeModel("gemini-2.5-pro-preview-05-06")

For production deployments, always pin to a specific model version. You can find the current version strings in Google AI Studio or by calling genai.list_models(). Schedule a deliberate review process when you want to upgrade, rather than letting it happen automatically.


When Gemini API output feels "wrong," start with finish_reason — it resolves the majority of cases immediately. Then work through the checklist above based on what you observe.

The single most actionable thing you can do right now: add finish_reason logging to your existing API calls. Having that data available when something breaks saves enormous debugging time later.

For more on controlling Gemini API responses, see the Gemini API rate limit error guide and structured output production guide.

Share

Thank You for Reading

Gemini Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

◈ API / SDK2026-10-14
When Your config Raises "Extra inputs are not permitted", Check the Spelling of Every Key
If a google-genai call fails with a pydantic ValidationError (extra_forbidden) the moment you pass a config, it is almost always a one-letter typo. Here is the output I reproduced, a small function that checks keys before the call, and how to tell why response.text came back as None.
◈ API / SDK2026-09-29
The Size Column Said 'F6' and 'About A4' — I Let Gemini Read It, and Let a Table Do the Math
An artist's spreadsheet mixed 'F6', '41×31.8cm', and 'about A4' in one size column. Here is the small tool I built: Gemini reads each cell, a lookup table converts to centimeters, and the artwork image decides the orientation. Working code, step by step.
◈ API / SDK2026-08-27
Record what you send before you try to measure whether temperature still works
Deprecated sampling parameters still return 200 and are silently ignored. Here is how a runtime recorder caught the call sites grep and AST both missed, kept the construction site attached to each config, and turned the ledger into a CI gate.