API Troubleshooting11 min

Nano Banana Pro Returns Text Instead of Image: Current Gemini 3 Pro Image Fix

Fix Gemini 3 Pro Image and Nano Banana Pro API responses that return text instead of image data. Covers Interactions API output_image parsing, stale model IDs, legacy responseModalities, safety blocks, and gateway checks.

API Integration Specialist
API Integration Specialist
Gemini API Expert
28 дек. 2025 г.
Обновлено 8 июл. 2026 г.
11 min
Nano Banana Pro Returns Text Instead of Image: Current Gemini 3 Pro Image Fix
yingtu.ai

Содержание

Заголовки не найдены

If Nano Banana Pro returns a text description instead of an image, start with the current API boundary: Google's stable Gemini 3 Pro Image model ID is gemini-3-pro-image, and Google's current image-generation docs show the Interactions API as the default path. In the current SDK examples, generated image bytes are exposed through interaction.output_image, not through the old candidates[0].content.parts[].inlineData pattern.

This page was refreshed on July 8, 2026. It separates current Interactions API fixes from legacy generateContent fixes because many "text instead of image" bugs come from mixing the two API surfaces in the same codebase.

Fast Diagnosis

Use this table before changing code:

SymptomMost likely causeFirst fix
You only get prose such as "Here is an image..."Prompt or API route is producing text, not an image blockUse gemini-3-pro-image with Interactions API and inspect interaction.output_image
output_image is emptySafety block, non-image prompt, wrong model, or response is interleavedLog the full interaction, check steps, safety, and model ID
Legacy REST returns only text partsMissing or wrong generationConfig.responseModalitiesInclude "IMAGE" for legacy generateContent calls
404 or model not foundOld preview model ID or wrong endpointReplace gemini-3-pro-image-preview with gemini-3-pro-image in official Google calls
Works in AI Studio but not codeSDK version, endpoint, env var, or response parsing mismatchReproduce with a minimal Interactions request
Gateway route behaves differentlyProvider compatibility layer maps fields differentlyCheck provider docs, console route, logs, and billing record

For a broader integration baseline, use the current Nano Banana Pro API integration guide. For quota and 429 behavior, use the Gemini 3 Pro Image API quota guide.

Current Official Path: Interactions API

Google's image-generation docs show text-to-image generation through the Interactions API:

hljs python
import base64
from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3-pro-image",
    input="Create a clean product photo of wireless earbuds on a marble surface, soft studio lighting.",
)

if not interaction.output_image:
    raise RuntimeError("No image returned. Inspect the full interaction before retrying.")

with open("output.png", "wb") as f:
    f.write(base64.b64decode(interaction.output_image.data))

JavaScript:

hljs javascript
import { GoogleGenAI } from "@google/genai";
import * as fs from "node:fs";

const ai = new GoogleGenAI({});

const interaction = await ai.interactions.create({
  model: "gemini-3-pro-image",
  input: "Create a clean product photo of wireless earbuds on a marble surface, soft studio lighting.",
});

const image = interaction.output_image;

if (!image?.data) {
  throw new Error("No image returned. Log the full interaction and inspect safety or response steps.");
}

fs.writeFileSync("output.png", Buffer.from(image.data, "base64"));

REST:

hljs bash
curl -s -X POST \
  "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3-pro-image",
    "input": [
      {
        "type": "text",
        "text": "Create a clean product photo of wireless earbuds on a marble surface, soft studio lighting."
      }
    ]
  }'

The practical fix is not "look harder for a URL." Google's current examples return image data as base64. The helper property interaction.output_image returns the last generated image block. If your response contains complex interleaved text and images, inspect the interaction steps rather than relying only on the convenience property.

Why You May Still See Text

There are five common causes.

1. Old Model ID

For official Google calls, use:

hljs text
gemini-3-pro-image

Do not treat gemini-3-pro-image-preview as the current official model ID. Google's Gemini 3 Pro Image model page lists gemini-3-pro-image as stable and says Interactions API is generally available for the latest features and models.

2. Prompt Sounds Like a Description Request

Image models can return text when the prompt asks for analysis, planning, or a description instead of generation. Make the image task explicit:

hljs text
Create an image: a 16:9 product launch hero visual for a matte black smart speaker on a neutral studio background.

If you ask "describe a product hero image for..." you should not be surprised when the model describes it.

3. Safety or Rights Issue

Google reminds developers to have rights to uploaded images and not to generate deceptive, harmful, abusive, or rights-infringing content. A blocked or constrained response can look like a text-only answer. Log the full interaction and the prompt context before retrying.

4. Legacy generateContent Configuration

If you are maintaining older generateContent code, then responseModalities still matters. A legacy request that asks only for text, or omits image output, can produce a text-only response.

hljs json
{
  "contents": [
    {
      "role": "user",
      "parts": [
        { "text": "Create an image of a red apple on a white table." }
      ]
    }
  ],
  "generationConfig": {
    "responseModalities": ["IMAGE"]
  }
}

For mixed text and image output:

hljs json
{
  "generationConfig": {
    "responseModalities": ["TEXT", "IMAGE"]
  }
}

Keep this rule scoped to legacy generateContent code. Do not paste a legacy request body into the Interactions endpoint and expect it to behave the same way.

5. Parser Assumes the Wrong Response Shape

Old code often scans candidates[0].content.parts for inlineData. Current Interactions examples use interaction.output_image. If you migrated only the endpoint and model name, but not the parser, your app may throw away the image block or report "no image" incorrectly.

Current Model Reference

Name readers useCurrent official model IDUse in official Google calls?
Nano Banana Progemini-3-pro-imageYes
Nano Banana 2gemini-3.1-flash-imageYes, for faster general image work
Nano Bananagemini-2.5-flash-imageLegacy; Google recommends moving to newer Nano Banana 2 Lite for many users
Preview-flavored aliasesvaries by provider or legacy codeVerify before using

This matters because a 404, a text-only fallback, or a missing image can be caused by a model mismatch before your prompt ever reaches the expected image model.

Step-by-Step Troubleshooting

  1. Confirm the official model ID is gemini-3-pro-image.
  2. Confirm your endpoint is https://generativelanguage.googleapis.com/v1beta/interactions if you are using Interactions API.
  3. Reproduce with the smallest possible prompt: Create an image of a red apple on a white table.
  4. Inspect interaction.output_image first.
  5. If output_image is empty, log the full interaction object before retrying.
  6. If you are using legacy generateContent, confirm "IMAGE" is present in generationConfig.responseModalities.
  7. Check whether the prompt may trigger safety, rights, or policy restrictions.
  8. Check rate limits only after the request shape is correct; Google's rate limits are project-level and model-specific.
  9. If a gateway is involved, verify the provider route string, response shape, logs, and billing record.

A Safer Debug Wrapper

hljs python
import base64
from pathlib import Path
from google import genai

client = genai.Client()


def generate_image_or_debug(prompt: str, output_path: str = "output.png") -> dict:
    interaction = client.interactions.create(
        model="gemini-3-pro-image",
        input=f"Create an image: {prompt}",
    )

    image = getattr(interaction, "output_image", None)
    if image and image.data:
        Path(output_path).write_bytes(base64.b64decode(image.data))
        return {"success": True, "image_path": output_path}

    return {
        "success": False,
        "reason": "No output_image returned",
        "debug_hint": "Log the full interaction, check safety, model ID, endpoint, and prompt wording.",
    }

Do not retry this wrapper blindly. If the problem is a prompt, safety state, parser mismatch, or wrong route, retries only add cost and noise.

Legacy generateContent Parser

If you cannot migrate immediately, parse legacy responses defensively:

hljs python
import base64
from pathlib import Path


def save_legacy_image_response(result: dict, output_path: str = "output.png") -> dict:
    parts = (
        result.get("candidates", [{}])[0]
        .get("content", {})
        .get("parts", [])
    )

    text_parts = []

    for part in parts:
        if "inlineData" in part:
            Path(output_path).write_bytes(base64.b64decode(part["inlineData"]["data"]))
            return {"success": True, "image_path": output_path, "text": text_parts}
        if "text" in part:
            text_parts.append(part["text"])

    return {
        "success": False,
        "text": text_parts,
        "debug_hint": "Legacy response contained no inlineData image block.",
    }

This keeps a legacy app from incorrectly reporting success just because a 200 response contained text.

Rate Limits Are A Separate Problem

A 429 error is not the same as "text instead of image." Google's rate-limit docs say limits are applied per project, vary by model, and can be viewed in AI Studio. They also warn that specified limits are not guaranteed.

Handle rate limits after the response-shape bug is fixed:

ProblemCorrect response
output_image is missinginspect prompt, safety, model ID, endpoint, and parser
429 RESOURCE_EXHAUSTEDbackoff with jitter, queue requests, reduce expensive calls, or request a limit increase
no image plus billed requestpreserve request ID, response body, logs, and billing evidence
gateway mismatchverify route, provider response shape, and provider support notes

For 429-only debugging, use the Gemini image generation error 429 fix guide.

Gateway and OpenAI-Compatible Routes

A third-party gateway can be useful when it lowers integration friction, adds local payment options, or provides a fallback lane. It can also change the response shape, model route name, failure handling, and billing semantics.

If a gateway returns text instead of an image:

  • verify the provider's current route string maps to Gemini 3 Pro Image,
  • confirm whether the provider expects OpenAI-compatible image syntax or Gemini-native syntax,
  • inspect provider logs and order records,
  • check whether failed or text-only responses are billed,
  • keep the gateway behind a provider adapter so official and gateway routes can be compared.

Do not treat a gateway as a way to ignore official model names, rights checks, safety states, or response parsing.

FAQ

Should I still use responseModalities?

Use it only for legacy generateContent requests. For current Interactions API examples, inspect interaction.output_image and the interaction steps.

Why does AI Studio generate an image but my code returns text?

Usually your code differs in model ID, endpoint, prompt wording, SDK version, or response parsing. Reproduce with the smallest Interactions API call before adding advanced parameters.

Can I force Gemini 3 Pro Image to return no text at all?

You can write an image-only prompt and save only output_image, but you should still handle text-only or no-image states. Safety, rights, or prompt interpretation can still produce non-image output.

Is gemini-3-pro-image-preview still correct?

Not for new official Google integrations. Use gemini-3-pro-image. If a provider route still uses preview-like naming, verify it as a provider-specific alias rather than a universal official model ID.

Why does my parser find no URL?

Google's current examples save base64 image data from interaction.output_image.data. Do not expect a hosted image URL unless a specific gateway creates one.

Bottom Line

For current Nano Banana Pro API work, fix text-only responses by using gemini-3-pro-image, calling the Interactions API, and checking interaction.output_image. Use responseModalities only when maintaining older generateContent code. If the image block is still missing, inspect the full interaction for prompt, safety, model, endpoint, parser, quota, or gateway-route issues instead of retrying blindly.

Теги

Поделиться статьей

XTelegram