Saltar al contenido principal

Nano Banana 2 blockReason OTHER: qué significa y qué revisar

Google define blockReason OTHER como un prompt bloqueado por motivos desconocidos: no hay imagen ni categoría. Guarda la respuesta y cambia una sola variable.

LaoZhang AI TeamPublicadoActualizado 11 min de lectura
En esta página
blockReason OTHER en Nano Banana 2: promptFeedback.blockReason con valor OTHER, cero candidatos y un motivo que Google no publica

Si una llamada generateContent a Nano Banana 2 (gemini-3.1-flash-image) o a Nano Banana Pro (gemini-3-pro-image) devuelve "promptFeedback": {"blockReason": "OTHER"} sin ningún candidato, Google ha bloqueado el prompt antes de generar nada y no te dice por qué. La referencia de la API define ese valor como «Prompt was blocked due to unknown reasons»: bloqueado por motivos desconocidos. No es una categoría de seguridad que puedas ajustar ni el nombre de una lista concreta de temas prohibidos, y cualquier causa exacta que leas en foros es una hipótesis.

Lo que sí puedes hacer: guardar la respuesta completa, confirmar cuál de los tres OTHER posibles tienes, repetir la misma petición como mucho una vez, cambiar una sola variable en cada prueba y, si un prompt inofensivo también se bloquea, reportarlo a Google con el responseId y la hora. Esquivar la política de contenido con proxies, cambios de región, nombres disfrazados o peticiones troceadas no forma parte del diagnóstico.

Qué significa blockReason OTHER según la referencia de la API de Google

La referencia de generateContent (actualizada el 23 de septiembre de 2026) describe así el campo promptFeedback.blockReason: si está presente, el prompt se bloqueó y no se devuelve ningún candidato; la indicación que acompaña al campo es reformular el prompt. Los valores posibles son estos:

blockReasonDefinición de Google
BLOCK_REASON_UNSPECIFIEDValor por defecto; no se usa
SAFETYBloqueado por motivos de seguridad; safetyRatings indica qué categoría lo bloqueó
OTHERBloqueado por motivos desconocidos
BLOCKLISTContiene términos de la lista de bloqueo terminológica
PROHIBITED_CONTENTContenido prohibido
IMAGE_SAFETYCandidatos bloqueados por contenido de generación de imagen no seguro

Comparado con sus vecinos, OTHER es el único que no nombra ningún motivo. SAFETY remite a safetyRatings, BLOCKLIST y PROHIBITED_CONTENT dicen qué tipo de contenido saltó; OTHER solo confirma dos hechos: la petición se bloqueó y no hay candidatos. Lo que queda sin decir es qué regla o qué sistema tomó la decisión, si el detonante fue el texto, una imagen de referencia o la combinación, y si volverá a pasar con la misma petición.

El propio Google reconoce que la etiqueta sirve de poco. En un hilo del foro de desarrolladores del 29 de diciembre de 2025, Logan Kilpatrick, de Google, respondió que el equipo trabajaba en rehacer la forma de devolver los errores «Other» porque, tal como estaban, «no son útiles», y que esperaba tenerlo a principios de enero. El hilo «blockReason: OTHER» del foro de Google AI no tiene actualizaciones posteriores y, a 4 de octubre de 2026, la referencia sigue diciendo «unknown reasons».

En el SDK de Python (google-genai) el mismo campo se lee como response.prompt_feedback.block_reason, y response.candidates no trae ningún elemento. Comprueba ese campo antes de acceder a candidates[0].

Los tres OTHER de una respuesta de Nano Banana 2 y dónde aparece cada uno

Hay tres valores con «OTHER» en el nombre y viven en sitios distintos del JSON. Confundirlos lleva a buscar el arreglo equivocado.

Dónde apareceValorQué ha pasado según Google¿Hay candidato?
promptFeedback.blockReasonOTHEREl prompt se bloqueó por motivos desconocidosNo
candidates[].finishReasonOTHERLa generación se detuvo por un motivo desconocidoSí, sin resultado válido
candidates[].finishReasonIMAGE_OTHERLa generación de imagen se detuvo por «otro problema diverso»Sí, sin imagen

Los tres OTHER en el JSON de Nano Banana 2: promptFeedback.blockReason sin candidatos, finishReason OTHER y finishReason IMAGE_OTHER dentro de un candidato

El bloqueo a nivel de prompt tiene esta forma:

json
{
  "promptFeedback": {
    "blockReason": "OTHER"
  },
  "modelVersion": "gemini-3.1-flash-image",
  "responseId": "..."
}

Los otros dos llegan dentro de un candidato:

json
{
  "candidates": [
    {
      "content": { "role": "model" },
      "finishReason": "IMAGE_OTHER",
      "finishMessage": "..."
    }
  ]
}

Cuando el candidato trae finishReason, mira también finishMessage: la referencia indica que ese campo puede detallar por qué se paró la generación, algo que el bloqueo a nivel de prompt nunca ofrece. Los valores de finishReason sin «OTHER» (NO_IMAGE, IMAGE_SAFETY, IMAGE_PROHIBITED_CONTENT, IMAGE_RECITATION) y las respuestas 200 que solo traen texto se explican en Nano Banana no genera imagen en la API: diagnóstico y arreglo.

Si usas la Interactions API, que Google recomienda para proyectos nuevos, no verás ninguno de estos campos: esa interfaz devuelve status y steps en lugar de promptFeedback y candidates, y no admite ajustes de seguridad personalizados. generateContent se considera heredada, pero sigue plenamente admitida. La estructura de Interactions está en la misma guía de respuesta sin imagen.

Otra comprobación rápida es el ID del modelo. gemini-3.1-flash-image-preview y gemini-3-pro-image-preview se retiraron el 25 de junio de 2026, según la página de modelos obsoletos; el código que aún los use debe pasar a gemini-3.1-flash-image o gemini-3-pro-image antes de diagnosticar cualquier otra cosa.

Conclusiones que un blockReason OTHER no permite: categorías, BLOCK_NONE, región

Como Google no publica el motivo, varias explicaciones que circulan sobre OTHER no tienen respaldo en su documentación:

  • Que sea un «segundo filtro» o una capa de política con categorías fijas. Google no describe ninguna arquitectura por capas ni una lista de temas asociada a OTHER. Listas del tipo «estas ocho categorías activan OTHER» son deducciones de terceros.
  • Que BLOCK_NONE u OFF lo quiten. La guía de ajustes de seguridad permite ajustar cuatro categorías (acoso, incitación al odio, contenido sexual explícito y contenido peligroso) y aclara que hay protecciones básicas, como las relativas a la seguridad infantil, que bloquean siempre y no se pueden ajustar. Además, en los modelos Gemini 2.5 y 3 el umbral por defecto ya es OFF si no fijas ninguno. De ahí se deduce que tocar safetySettings no está pensado para quitar un OTHER. Es una inferencia, pero coincide con lo que se ha observado: en una pregunta de Stack Overflow del 6 de febrero de 2026, un equipo con todos los umbrales en BLOCK_NONE seguía recibiendo OTHER.
  • Que dependa de la región. Google no publica nada al respecto. En ese mismo hilo de Stack Overflow, un comentario sostiene que no es un filtro regional, sin aportar fuente. La respuesta que propone enrutar las peticiones por un proxy en Estados Unidos no está verificada y busca esquivar los controles del proveedor; no la uses.
  • Que sea temporal o permanente. Un OTHER aislado no dice si se repetirá. Solo una repetición controlada (siguiente sección) distingue un fallo intermitente de uno constante.

Los informes publicados de desarrolladores muestran en qué situaciones ha aparecido, no por qué. Los tres son de Nano Banana Pro, dos de ellos con el ID preview ya retirado:

FechaDóndeQué se observó
29 de diciembre de 2025Foro de Google AI DevelopersCon Nano Banana Pro desde AI Studio, una de cada cinco peticiones devolvía OTHER sin cambios aparentes
6 de febrero de 2026Stack OverflowPrompts con nombres de personajes públicos muy conocidos: OTHER con BLOCK_NONE, y también al reescribirlos sin nombres
7 de mayo de 2026Foro de Google AI DevelopersEn AI Studio, bloqueo con «Other» cada vez que se adjuntaban imágenes de referencia; Google pidió los detalles por mensaje privado y no hay resolución pública

Sirven para formular hipótesis que puedes probar con tus propias peticiones, no como reglas.

Qué guardar de cada respuesta con blockReason OTHER antes de cambiar nada

Antes de reformular o reintentar, guarda la respuesta tal cual llegó. Google no publica una lista de requisitos para reportar un OTHER, pero estos campos documentados identifican la llamada y permiten comparar casos:

  • responseId: identifica cada respuesta.
  • modelVersion: la versión del modelo que atendió la petición, además del ID que enviaste.
  • El objeto promptFeedback completo, incluido safetyRatings si viene.
  • usageMetadata: promptTokenCount, candidatesTokenCount y thoughtsTokenCount, si aparecen.
  • En cada candidato, si los hay: finishReason y finishMessage.
  • La hora de la petición en UTC.
  • Si adjuntaste imágenes de referencia y cuántas, y las modalidades de respuesta configuradas.

Guarda el texto del prompt y las imágenes en privado. Si los compartes en un foro, hazlo con una copia anonimizada.

Para reproducir el caso fuera de tu aplicación, lanza la misma petición por REST y escribe el cuerpo en un archivo:

bash
curl -s -X POST \
  "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-flash-image:generateContent" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"contents": [{"parts": [{"text": "Ilustración de un faro en la costa gallega al atardecer"}]}]}' \
  -o respuesta.json

Script en Python que clasifica la respuesta guardada

Este script lee un JSON de generateContent guardado (con los nombres de campo de REST, en camelCase) y lo clasifica en uno de cinco estados: api_error, prompt_blocked (cualquier blockReason distinto de BLOCK_REASON_UNSPECIFIED, incluidos OTHER y valores que Google añada en el futuro), candidate_stopped, image_ready o no_image. Ignora las imágenes de razonamiento (thought), comprueba que el MIME sea PNG, JPEG o WebP, que el base64 se decodifique, que haya bytes y que Pillow abra una imagen del formato declarado, y solo acepta la imagen si el candidato terminó con STOP.

python
import base64
import binascii
import io
import json
import sys
from pathlib import Path

from PIL import Image, UnidentifiedImageError

FORMATS = {"image/png": "PNG", "image/jpeg": "JPEG", "image/webp": "WEBP"}


def as_dict(value):
    return value if isinstance(value, dict) else {}


def as_list(value):
    return value if isinstance(value, list) else []


def inspect_response(response):
    if not isinstance(response, dict):
        raise ValueError("La raíz de la respuesta debe ser un objeto JSON")

    feedback = as_dict(response.get("promptFeedback"))
    block = feedback.get("blockReason")
    report = {
        "status": "no_image",
        "response_id": response.get("responseId"),
        "model_version": response.get("modelVersion"),
        "usage": response.get("usageMetadata"),
        "block_reason": block,
        "prompt_safety_ratings": as_list(feedback.get("safetyRatings")),
        "candidates": [],
        "images": [],
    }
    if response.get("error"):
        report["status"] = "api_error"
        return report
    # Cualquier blockReason distinto de BLOCK_REASON_UNSPECIFIED (incluido OTHER
    # y valores futuros) significa que el prompt se bloqueó y no hay candidatos.
    if block and block != "BLOCK_REASON_UNSPECIFIED":
        report["status"] = "prompt_blocked"
        return report

    candidates = as_list(response.get("candidates"))
    for ci, raw_candidate in enumerate(candidates):
        candidate = as_dict(raw_candidate)
        reason = candidate.get("finishReason")
        entry = {
            "index": ci,
            "finish_reason": reason,
            "finish_message": candidate.get("finishMessage"),
            "safety_ratings": as_list(candidate.get("safetyRatings")),
            "image_issues": [],
        }
        report["candidates"].append(entry)
        content = as_dict(candidate.get("content"))
        for pi, raw_part in enumerate(as_list(content.get("parts"))):
            part = as_dict(raw_part)
            # Las imágenes de razonamiento (thought) no son el resultado final.
            if part.get("thought"):
                continue
            blob = as_dict(part.get("inlineData"))
            if not blob:
                continue
            mime = blob.get("mimeType")
            encoded = blob.get("data")
            problem = None
            data = b""
            if not isinstance(mime, str) or mime not in FORMATS:
                problem = "unsupported_mime"
            elif not isinstance(encoded, str) or not encoded:
                problem = "empty_or_missing_data"
            else:
                try:
                    data = base64.b64decode(encoded, validate=True)
                    if not data:
                        raise ValueError("empty bytes")
                    with Image.open(io.BytesIO(data)) as img:
                        actual_format = img.format
                        img.load()
                    if actual_format != FORMATS[mime]:
                        raise ValueError("MIME does not match image format")
                except (ValueError, binascii.Error, OSError,
                        UnidentifiedImageError, Image.DecompressionBombError):
                    problem = "invalid_image_data"
            if problem:
                entry["image_issues"].append({"part": pi, "reason": problem})
            # Solo se acepta la imagen si el candidato terminó con STOP.
            elif reason == "STOP":
                report["images"].append({
                    "candidate": ci, "part": pi, "mime_type": mime, "data": data
                })
            else:
                entry["image_issues"].append({
                    "part": pi, "reason": "finish_reason_requires_review"
                })

    if report["images"]:
        report["status"] = "image_ready"
    elif any(c["finish_reason"] not in (None, "STOP", "FINISH_REASON_UNSPECIFIED")
             for c in report["candidates"]):
        report["status"] = "candidate_stopped"
    return report


if __name__ == "__main__":
    response = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
    result = inspect_response(response)
    # Muestra solo un resumen: ni datos binarios ni el JSON completo en la terminal.
    print(json.dumps({
        "status": result["status"],
        "block_reason": result["block_reason"],
        "finish_reasons": [c["finish_reason"] for c in result["candidates"]],
        "image_count": len(result["images"]),
        "image_issues": [c["image_issues"] for c in result["candidates"]],
    }, ensure_ascii=False, indent=2))

Guárdalo como inspect_response.py, instala Pillow (pip install pillow) y ejecútalo sobre el archivo: python3 inspect_response.py respuesta.json. Con un bloqueo OTHER a nivel de prompt, la salida es esta:

json
{
  "status": "prompt_blocked",
  "block_reason": "OTHER",
  "finish_reasons": [],
  "image_count": 0,
  "image_issues": []
}

El script se probó en local (Python 3.12.1, Pillow 12.0.0) con 29 respuestas JSON escritas a mano: sin candidatos, candidatos nulos o vacíos, solo texto, OTHER, SAFETY y un motivo de bloqueo inventado a nivel de prompt, OTHER y NO_IMAGE en el candidato, base64 vacío o inválido, un PNG falso, MIME erróneo, imágenes de razonamiento, una imagen válida con finishReason: "OTHER", dos candidatos, un error de la API y una raíz que no es un objeto. Las 29 dieron el resultado esperado. No se hizo ninguna llamada a la API de Gemini, así que la prueba demuestra que cada rama del código funciona con esas formas de JSON, no cómo responde Google.

Si guardas la respuesta desde el SDK de Python, ten en cuenta que su volcado usa snake_case (prompt_feedback, finish_reason); el script espera los nombres de REST, por eso conviene reproducir el caso con la petición curl anterior.

Repetir, cambiar una variable o reportar: cómo actuar ante un OTHER

Trata prompt_blocked como un resultado propio en tu código: ni éxito ni un error transitorio que se reintenta en bucle como un 429 o un 503. Google no publica una política de reintentos para OTHER; las reglas siguientes son una forma razonable de llegar a algo concluyente sin gastar llamadas a ciegas.

  1. Repite la misma petición una sola vez. Si la segunda sale bien, el bloqueo fue intermitente, como en el informe de diciembre de 2025. Registra la frecuencia en lugar de reintentar sin límite. Si vuelve a fallar, el bloqueo depende de la petición.
  2. Lanza un prompt de control inofensivo con el mismo modelo, la misma clave y el mismo proyecto, por ejemplo el del curl anterior. Si también devuelve OTHER, el problema no está en tu contenido: deja de modificar prompts y pasa al paso 5.
  3. Cambia una sola variable y vuelve a probar. Quita las imágenes de referencia y deja el texto igual; o deja las imágenes con un texto neutro; o prueba el mismo prompt con el otro modelo (Nano Banana 2 frente a Nano Banana Pro). Así sabrás qué parte de la petición está ligada al bloqueo. Si cambias tres cosas a la vez y funciona, no sabrás cuál importaba.
  4. Para si el bloqueo sigue a lo que pides. Si el OTHER solo aparece cuando la imagen representa a una persona real reconocible o reproduce algo que no es tuyo, y desaparece al quitarlo, no lo reintroduzcas con otras palabras ni por partes. Describir sin nombrarlo lo que el modelo ha rechazado no arregla nada: es intentar saltarse el bloqueo.
  5. Reporta cuando el contenido es legítimo y el bloqueo es constante: el prompt de control falla, el OTHER aparece con imágenes de referencia propias e inofensivas o todo empezó a fallar de golpe sin cambios en tu código. Publica en el foro de Google AI Developers el modelo, la hora UTC, el responseId y el promptFeedback de dos o tres casos, más una descripción anonimizada de la petición. En los hilos citados, el personal de Google pidió los detalles por mensaje privado.

Cinco pasos ante un blockReason OTHER: repetir una vez, prompt de control, cambiar una variable, parar si el bloqueo sigue al contenido y reportar con responseId

Para que tu aplicación no se quede colgada, asigna a cada estado del script una acción distinta:

EstadoAcción en producción
image_readyGuarda la imagen y continúa
prompt_blockedRegistra la respuesta, avisa al usuario de que la petición se bloqueó, permite como mucho una repetición
candidate_stoppedRegistra finishReason y finishMessage; con IMAGE_OTHER u OTHER, aplica la misma regla de una repetición
no_imageRevisa la configuración de la petición con la guía de respuesta sin imagen
api_errorGestiona el código HTTP; para 429 y 503, consulta Nano Banana API no funciona: arregla 429, 503, sin imagen y request denied

Lleva también la cuenta de cuántas respuestas acaban en prompt_blocked por modelo y por día. Un salto repentino con el mismo tráfico es el patrón de los informes de «antes funcionaba y ahora se bloquea todo», y es una buena señal para reportarlo con datos.

¿Te cobran una petición bloqueada con OTHER? Mira usageMetadata

Google no publica una regla que diga si un prompt bloqueado con blockReason (sin candidatos) se factura como una imagen, ni que sea gratis. La forma de saberlo con tu cuenta es mirar el usageMetadata de esa misma respuesta (promptTokenCount, candidatesTokenCount, thoughtsTokenCount) y contrastarlo con el informe de facturación de tu proyecto. Si candidatesTokenCount no aparece o vale cero, esa respuesta no tuvo tokens de salida; lo que acabe cobrándose lo dice el informe, no la etiqueta del error.

Si llamas al modelo a través de una pasarela de terceros, la facturación la fija esa pasarela, y puede contar como llamada una respuesta sin imagen. Consulta su documentación y sus registros de llamadas.

Preguntas frecuentes sobre blockReason OTHER

¿Por qué Nano Banana funcionaba y de repente todo da blockReason OTHER?

Google no publica cambios que expliquen un salto así. Primero descarta tu parte: comprueba que no uses un ID preview retirado el 25 de junio de 2026 y lanza un prompt de control inofensivo. Si el control también se bloquea sin cambios en tu código, guarda varias respuestas con responseId y hora UTC y repórtalo en el foro de desarrolladores.

¿Por qué solo da blockReason OTHER cuando adjunto imágenes de referencia?

No hay explicación publicada; el informe del 7 de mayo de 2026 describe exactamente ese patrón con Nano Banana Pro en AI Studio, sin resolución pública. Prueba el mismo texto sin imágenes y las mismas imágenes con un texto neutro para confirmar que el bloqueo va ligado a las imágenes. Si son tuyas y no muestran nada problemático, repórtalo con esos dos resultados.

¿Poner los ajustes de seguridad en BLOCK_NONE quita el blockReason OTHER?

No cabe esperarlo. BLOCK_NONE y OFF solo afectan a las cuatro categorías ajustables, y en los modelos Gemini 3 el umbral ya es OFF si no fijas ninguno. OTHER no corresponde a ninguna de esas categorías, y hay casos publicados de OTHER con todos los umbrales en BLOCK_NONE.

¿Es blockReason OTHER un error de Nano Banana 2 o de Nano Banana Pro?

El campo es común a todos los modelos que usan generateContent; el enum BlockReason no distingue entre modelos. Los informes publicados son sobre todo de Nano Banana Pro, pero el diagnóstico es el mismo para gemini-3.1-flash-image y gemini-3-pro-image.

¿Qué hago si veo «generación bloqueada» en la app de Gemini y no en la API?

La app de Gemini no te enseña la respuesta JSON, así que este diagnóstico por campos no aplica. Para ese caso está Nano Banana Pro no funciona en Gemini: botón ausente o generación bloqueada. Otros errores de la API tienen su propia guía: Nano Banana 2 Error 503 "Model is Overloaded": 6 Soluciones Probadas (2026) para la sobrecarga y Error de Thought Signature en Nano Banana 2: Guía completa de solución (2026) para MISSING_THOUGHT_SIGNATURE.

Documentación oficial

Los parámetros de la solicitud, los precios y las reglas de cobro están en la documentación para desarrolladores de LaoZhang API: facturación y fallos en la generación de imágenes.

Aviso: laozhang.ai es un servicio propio. Sus precios son nuestra tarifa, no una comparación independiente.

Fuentes7

Páginas externas que cita esta guía, en el orden en que aparecen. Última actualización: 4 oct 2026.

  1. 1.referencia de generateContentai.google.dev/api/generate-content
  2. 2.hilo «blockReason: OTHER» del foro de Google AIdiscuss.ai.google.dev/t/blockreason-other/113496
  3. 3.página de modelos obsoletosai.google.dev/gemini-api/docs/deprecations
  4. 4.guía de ajustes de seguridadai.google.dev/gemini-api/docs/safety-settings
  5. 5.pregunta de Stack Overflowstackoverflow.com/questions/79884545
  6. 6.Foro de Google AI Developersdiscuss.ai.google.dev/t/persistent-other-block-reason-error-on-nano-banana-pro-gemini-3-pro-image-preview-with-reference-images/143901
  7. 7.foro de Google AI Developersdiscuss.ai.google.dev
Recuperación de Nano Banana 2 ante 503 con reintentos limitados, tarea pendiente e imagen final comprobada
Resolución de problemas

Nano Banana 2: qué hacer ante el error 503 «Model is overloaded»

Si Nano Banana 2 devuelve un 503 «Model is overloaded», reintenta con esperas variables y un límite total. Cuando ese límite se agota, conserva la tarea para después; una respuesta 200 solo cuenta como éxito si contiene una imagen utilizable.

10 min