|

Resolución de 6 causas comunes y métodos de reparación para el error «required oneof field data» del Modelo de Lenguaje Grande Gemini para generación de imágenes

gemini-image-api-required-oneof-field-data-error-fix-es 图示

Al invocar modelos de Gemini como gemini-3.1-flash-image-preview (Nano Banana 2) o gemini-3.0-pro-image (Nano Banana Pro) para generar imágenes, muchos desarrolladores se han encontrado con este confuso error 400:

{
  "status_code": 400,
  "error": {
    "message": "* GenerateContentRequest.contents[0].parts[2].data: required oneof field 'data' must have one initialized field",
    "type": "upstream_error",
    "code": 400
  }
}

El significado central de este error es: En el cuerpo de tu solicitud, el campo data de algún elemento parts está vacío o tiene un formato incorrecto. El error 400 es un error del lado del cliente (parámetros de solicitud erróneos) y no se resolverá automáticamente; debes corregir tu código.

Este artículo resume 6 causas comunes que provocan este error, cada una acompañada de una comparación entre el código erróneo y el correcto, para ayudarte a localizar y solucionar el problema rápidamente.

Valor clave: Después de leer este artículo, podrás localizar con precisión la posición del problema usando el número de índice parts[N] en el mensaje de error, y revisar una por una las 6 causas. Normalmente, podrás solucionarlo en menos de 5 minutos.


Análisis central del error "required oneof field data" en modelos de imagen de Gemini

Punto clave Descripción Dirección de investigación
Naturaleza del error Elementos vacíos o con formato incorrecto en el array parts Verificar cada elemento en contents[].parts[]
Pista clave parts[2] representa el tercer elemento (contando desde 0) Localizar directamente la parte en el índice correspondiente
Tipo de error 400 INVALID_ARGUMENT, error del cliente No se recupera automáticamente, se debe modificar el código
Alcance del impacto Común a todos los modelos de imagen de Gemini Aplica a NB2, NB Pro, Gemini Flash
Dificultad de reparación Baja, generalmente es un problema de formato Basta con modificar según el formato correcto

Interpretación de la estructura del mensaje de error del modelo de imagen de Gemini

Primero, desglosemos la estructura del mensaje de error, esto es clave para localizar el problema:

GenerateContentRequest.contents[0].parts[2].data
                       ^^^^^^^^     ^^^^^^^^
                       │            │
                       │            └── Tercera parte (índice comienza en 0)
                       └── Primer bloque de contenido
  • contents[0]: Apunta al primer objeto de contenido en el cuerpo de tu solicitud.
  • parts[2]: Apunta al tercer elemento de la parte en ese contenido.
  • data: El campo de datos de esa parte está vacío o no se inicializó correctamente.

Lógica de investigación: Revisa directamente el elemento [2] del array parts dentro del elemento [0] del array contents en tu código, para ver qué se está enviando realmente.

Flujo de resolución de errores Sigue estos tres pasos para diagnosticar y corregir el error "required oneof field data"

Paso 1 Leer mensaje de error Busca la línea que contiene «GenerateContentRequest.contents» contents[0].parts[2].data

Paso 2 Localizar código Encuentra el array `contents` en tu código de solicitud contents[0][«parts»][2]

Paso 3 Reparar problema Verifica el contenido de la parte y corrige según las causas comunes Verificar/Corregir datos

Consulta rápida de problemas comunes

Objeto vacío {} en parts

Base64 vacío data: ""

Formato incorrecto Prefijo data:image

Historial vacío parts: []

Mayúsculas/minúsculas inline_data vs inlineData

Consulta las soluciones detalladas a continuación


6 causas comunes y métodos de reparación para errores en modelos de imagen de Gemini

Causa 1: Objetos vacíos o cadenas vacías en parts

Esta es la causa más común. El array parts de la solicitud contiene elementos vacíos como {}, null, cadenas vacías "", etc.

Escritura incorrecta Escritura correcta
parts contiene objetos vacíos {} Cada parte debe tener text o inlineData
parts contiene {"text": ""} El texto vacío también activa el error, escribe al menos un carácter
parts contiene elementos null Elimina todos los valores null

Código incorrecto:

# ❌ parts contiene objetos vacíos
payload = {
    "contents": [{
        "parts": [
            {"text": "Genera una imagen de un gato"},
            {},                              # ← Objeto vacío, activa el error
            {"text": "en estilo acuarela"}
        ]
    }]
}

Código correcto:

# ✅ Cada parte tiene contenido válido
payload = {
    "contents": [{
        "parts": [
            {"text": "Genera una imagen de un gato en estilo acuarela"}
        ]
    }]
}

Puntos de reparación: Combina el texto en una sola parte text, o asegúrate de que cada parte contenga campos válidos text o inlineData.

Causa 2: Datos base64 de imagen vacíos o con formato incorrecto

Cuando envías una solicitud de imagen a imagen (image-to-image), los datos base64 en inlineData pueden estar vacíos, corruptos o con formato incorrecto.

Código incorrecto:

# ❌ Los datos base64 incluyen el prefijo data URI
payload = {
    "contents": [{
        "parts": [
            {
                "inlineData": {
                    "mimeType": "image/png",
                    "data": "data:image/png;base64,iVBORw0KGgo..."  # ← No debe contener prefijo
                }
            },
            {"text": "Cambia el fondo a azul"}
        ]
    }]
}
# ❌ Los datos base64 son una cadena vacía
"inlineData": {
    "mimeType": "image/jpeg",
    "data": ""          # ← Datos vacíos, activan el error directamente
}

Código correcto:

import base64
import pathlib

# ✅ Leer correctamente la imagen y convertirla a base64 puro
image_bytes = pathlib.Path("input.png").read_bytes()
image_b64 = base64.b64encode(image_bytes).decode("utf-8")

payload = {
    "contents": [{
        "parts": [
            {
                "inlineData": {
                    "mimeType": "image/png",
                    "data": image_b64       # ← Cadena base64 pura, sin prefijo
                }
            },
            {"text": "Cambia el fondo a azul"}
        ]
    }]
}

Puntos de reparación:

  • El campo data solo acepta cadenas base64 puras, no puede contener el prefijo data:image/png;base64,
  • Asegúrate de que el archivo de imagen exista realmente y se lea correctamente, evita pasar cadenas vacías
  • mimeType debe coincidir con el formato real de la imagen (image/png, image/jpeg, image/webp)

Causa 3: El objeto File no se convierte correctamente a referencia de contenido

Después de subir un archivo usando la API de Files del SDK de Google GenAI, pasar directamente el objeto File a contents puede hacer que el SDK no lo convierta correctamente.

Código incorrecto:

from google import genai

client = genai.Client(api_key="TU_CLAVE")

# Subir archivo
file = client.files.upload(file="foto.png")

# ❌ En algunas versiones del SDK, pasar directamente el objeto File falla
response = client.models.generate_content(
    model="gemini-3.1-flash-image-preview",
    contents=["Edita esta imagen", file]    # ← El objeto File puede no convertirse automáticamente
)

Código correcto:

from google import genai
from google.genai import types

client = genai.Client(api_key="TU_CLAVE")

# Subir archivo
file = client.files.upload(file="foto.png")

# ✅ Método 1: Construir manualmente la referencia al archivo
response = client.models.generate_content(
    model="gemini-3.1-flash-image-preview",
    contents=[
        types.Content(parts=[
            types.Part(file_data=types.FileData(file_uri=file.uri, mime_type=file.mime_type)),
            types.Part(text="Edita esta imagen: cambia el fondo a atardecer")
        ])
    ],
    config=types.GenerateContentConfig(
        response_modalities=["TEXT", "IMAGE"]
    )
)
# ✅ Método 2: Usar inlineData para pasar base64 directamente (más confiable)
import base64, pathlib

image_b64 = base64.b64encode(pathlib.Path("foto.png").read_bytes()).decode()

response = client.models.generate_content(
    model="gemini-3.1-flash-image-preview",
    contents=[
        types.Content(parts=[
            types.Part(inline_data=types.Blob(mime_type="image/png", data=image_b64)),
            types.Part(text="Edita esta imagen: cambia el fondo a atardecer")
        ])
    ],
    config=types.GenerateContentConfig(
        response_modalities=["TEXT", "IMAGE"]
    )
)

Puntos de reparación: Se recomienda usar el método inlineData + base64 para pasar los datos de la imagen directamente, es más estable y confiable que la API de Files.

Causa 4: El historial de conversación multironda contiene contenido vacío

Al editar imágenes en una conversación multironda, si la respuesta de la ronda anterior no se maneja correctamente, pueden mezclarse bloques de contenido vacíos en el historial.

Código incorrecto:

# ❌ El historial de conversación contiene partes vacías
historial = [
    {"role": "user", "parts": [{"text": "Genera un logo"}]},
    {"role": "model", "parts": []},        # ← parts vacío, activa el error
    {"role": "user", "parts": [{"text": "Hazlo azul"}]}
]

payload = {"contents": historial}

Código correcto:

# ✅ Filtrar bloques de contenido vacíos
historial = [
    {"role": "user", "parts": [{"text": "Genera un logo"}]},
    {"role": "model", "parts": [{"text": "Aquí está el logo que generé."}]},
    {"role": "user", "parts": [{"text": "Hazlo azul"}]}
]

# Filtrado seguro: eliminar registros donde parts esté vacío
historial_limpio = [msg for msg in historial if msg.get("parts") and len(msg["parts"]) > 0]

payload = {"contents": historial_limpio}

Puntos de reparación: Antes de enviar la solicitud, recorre el array contents y filtra todos los elementos donde parts sea una lista vacía o contenga objetos vacíos.

Causa 5: Error de mayúsculas/minúsculas en nombres de campos JSON en solicitudes REST API

Los nombres de campos JSON de la API de Gemini usan camelCase (nomenclatura camel), son sensibles a mayúsculas y minúsculas. Si el nombre del campo está mal escrito, se ignorará, lo que equivale a pasar datos vacíos.

Nombre de campo incorrecto Nombre de campo correcto Explicación
inline_data inlineData REST API usa camelCase
mime_type mimeType REST API usa camelCase
file_uri fileUri REST API usa camelCase
response_modalities responseModalities REST API usa camelCase
image_config imageConfig REST API usa camelCase
aspect_ratio aspectRatio REST API usa camelCase
image_size imageSize REST API usa camelCase

Código incorrecto:

# ❌ Se usa snake_case en REST API (estilo Python SDK)
payload = {
    "contents": [{
        "parts": [{
            "inline_data": {           # ← Debería ser inlineData
                "mime_type": "image/png",   # ← Debería ser mimeType
                "data": image_b64
            }
        }]
    }],
    "generation_config": {             # ← Debería ser generationConfig
        "response_modalities": ["IMAGE"]   # ← Debería ser responseModalities
    }
}

Código correcto:

# ✅ REST API usa camelCase
payload = {
    "contents": [{
        "parts": [{
            "inlineData": {
                "mimeType": "image/png",
                "data": image_b64
            }
        }]
    }],
    "generationConfig": {
        "responseModalities": ["IMAGE"],
        "imageConfig": {
            "aspectRatio": "1:1",
            "imageSize": "2K"
        }
    }
}

🎯 Recordatorio para evitar confusiones: El SDK de Python (google-genai) usa snake_case (como inline_data), mientras que las llamadas directas a REST API usan camelCase (como inlineData). Al llamar a través de plataformas intermediarias como APIYI apiyi.com, se usa el formato REST API, por lo que se debe usar camelCase.

Causa 6: Formato de imagen no compatible o archivo corrupto

La imagen pasada tiene datos base64, pero el formato de la imagen en sí no es compatible o el archivo está corrupto.

Formatos de entrada compatibles con modelos de imagen de Gemini:

Formato mimeType Estado de compatibilidad
PNG image/png Compatible
JPEG image/jpeg Compatible
WebP image/webp Compatible
GIF image/gif Compatibilidad parcial (solo primer fotograma)
BMP image/bmp No compatible
SVG image/svg+xml No compatible
TIFF image/tiff No compatible

Método de investigación:

import base64

# Verificar si los datos base64 son válidos
def validar_datos_imagen(cadena_b64, tipo_mime):
    # 1. Verificar si está vacío
    if not cadena_b64:
        print("ERROR: Los datos base64 están vacíos")
        return False

    # 2. Verificar si contiene el prefijo data URI
    if cadena_b64.startswith("data:"):
        print("ERROR: Elimina el prefijo 'data:image/...;base64,'")
        return False

    # 3. Verificar si base64 se puede decodificar
    try:
        decodificado = base64.b64decode(cadena_b64)
        print(f"OK: Tamaño decodificado = {len(decodificado)} bytes")
    except Exception as e:
        print(f"ERROR: Base64 inválido - {e}")
        return False

    # 4. Verificar si mimeType es compatible
    compatibles = ["image/png", "image/jpeg", "image/webp", "image/gif"]
    if tipo_mime not in compatibles:
        print(f"ERROR: Tipo mime '{tipo_mime}' no compatible")
        return False

    print("PASS: Los datos de la imagen son válidos")
    return True

💡 Sugerencia: Agregar una función de validación de datos antes de enviar la solicitud puede capturar la mayoría de los problemas de formato. También aplica al llamar a través de la plataforma APIYI apiyi.com.


Lista completa de verificación para errores del modelo de imágenes Gemini

Cuando encuentres el error required oneof field 'data', sigue esta lista de verificación paso a paso:

gemini-image-api-required-oneof-field-data-error-fix-es 图示

Paso de verificación Contenido a revisar Método de corrección
Paso 1 Verificar en qué posición (N) está el elemento parts[N] Ubicar directamente la posición correspondiente en el código
Paso 2 ¿Esa parte es {}, null o ""? Eliminar el elemento vacío o llenarlo con contenido válido
Paso 3 Si es inlineData, ¿está vacío el base64? Asegurarse de que la lectura del archivo de imagen fue exitosa
Paso 4 ¿El base64 contiene el prefijo data:? Eliminar el prefijo, mantener solo el base64 puro
Paso 5 ¿Los nombres de los campos JSON usan camelCase? La API REST debe usar inlineData, no inline_data
Paso 6 ¿El formato de imagen es compatible? Solo PNG/JPEG/WebP/GIF

Solución rápida: Si encuentras este error con frecuencia durante el desarrollo, se recomienda agregar una función validate_payload() antes de enviar la solicitud, para verificar automáticamente si cada elemento en el array parts es válido. Al invocar el modelo de imágenes Gemini a través de la plataforma APIYI apiyi.com, el formato de solicitud es completamente idéntico a la API REST oficial, por lo que los métodos de verificación anteriores también son aplicables.


Formato correcto de solicitud para evitar errores en el modelo de imágenes Gemini

Formato correcto para Texto a Imagen (Text-to-Image)

import requests, base64

API_KEY = "tu-clave-api-de-apiyi"
ENDPOINT = "https://api.apiyi.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent"

# ✅ Formato correcto más simple
payload = {
    "contents": [{
        "parts": [
            {"text": "Un lindo gato naranja sentado en el alféizar de una ventana, estilo acuarela, 4K"}
        ]
    }],
    "generationConfig": {
        "responseModalities": ["IMAGE"],
        "imageConfig": {
            "aspectRatio": "1:1",
            "imageSize": "2K"
        }
    }
}

response = requests.post(
    ENDPOINT,
    headers={"Content-Type": "application/json", "x-goog-api-key": API_KEY},
    json=payload,
    timeout=120
)

result = response.json()
image_data = result["candidates"][0]["content"]["parts"][0]["inlineData"]["data"]
with open("output.png", "wb") as f:
    f.write(base64.b64decode(image_data))

Formato correcto para Imagen a Imagen (Image-to-Image)

Ver el código completo correcto para Imagen a Imagen
import requests
import base64
import pathlib

API_KEY = "tu-clave-api-de-apiyi"
ENDPOINT = "https://api.apiyi.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent"

# Leer la imagen original y convertirla a base64 puro
image_path = pathlib.Path("input_photo.png")
if not image_path.exists():
    raise FileNotFoundError(f"Imagen no encontrada: {image_path}")

image_bytes = image_path.read_bytes()
image_b64 = base64.b64encode(image_bytes).decode("utf-8")

# Validar los datos
assert len(image_b64) > 0, "Los datos en base64 están vacíos"
assert not image_b64.startswith("data:"), "Elimina el prefijo 'data:' del URI"

# ✅ Formato correcto de solicitud para Imagen a Imagen
payload = {
    "contents": [{
        "parts": [
            {
                "inlineData": {
                    "mimeType": "image/png",
                    "data": image_b64
                }
            },
            {
                "text": "Cambia el fondo a una escena de playa al atardecer, mantén el sujeto sin cambios"
            }
        ]
    }],
    "generationConfig": {
        "responseModalities": ["IMAGE"],
        "imageConfig": {
            "aspectRatio": "1:1",
            "imageSize": "2K"
        }
    }
}

response = requests.post(
    ENDPOINT,
    headers={"Content-Type": "application/json", "x-goog-api-key": API_KEY},
    json=payload,
    timeout=120
)

if response.status_code == 200:
    result = response.json()
    output_data = result["candidates"][0]["content"]["parts"][0]["inlineData"]["data"]
    with open("output_edited.png", "wb") as f:
        f.write(base64.b64decode(output_data))
    print("¡Éxito! Imagen guardada.")
else:
    print(f"Error {response.status_code}: {response.text}")

Recomendación: Para escenarios de texto a imagen, se recomienda comenzar con el formato más simple, confirmar que funciona y luego agregar parámetros gradualmente. Al llamar a Nano Banana 2 a través de la plataforma APIYI en apiyi.com, el costo es de $0.045 por invocación, lo que lo hace muy económico durante la fase de desarrollo.


Preguntas frecuentes

P1: ¿Qué significa parts[2] en el mensaje de error?

parts[2] se refiere al elemento en el índice 2 del arreglo parts, es decir, el tercer elemento (los índices comienzan en 0). Simplemente localiza el tercer elemento del arreglo contents[0].parts en tu código y revisa su contenido. Si tu arreglo parts solo tiene 2 elementos (índices 0 y 1), significa que la lógica de tu código podría haber agregado accidentalmente un elemento vacío al concatenar las partes.

P2: ¿También ocurre este error al llamar a través de APIYI?

Sí. APIYI en apiyi.com actúa como un servicio proxy y reenvía tu solicitud al backend de Gemini. Si el cuerpo de la solicitud tiene problemas de formato, el backend devolverá el mismo error 400. APIYI no modifica la estructura de tu solicitud, por lo que es responsabilidad del desarrollador asegurar que el formato sea correcto. La buena noticia es que el método de corrección es exactamente el mismo que al llamar directamente a la API de Google.

P3: ¿Por qué los nombres de los campos son diferentes en el SDK de Python y en la API REST?

El SDK de Google GenAI para Python sigue la convención de nomenclatura snake_case de Python (por ejemplo, inline_data, mime_type). El SDK convierte internamente estos nombres al formato camelCase requerido por la API. Sin embargo, si llamas directamente a la API REST usando la biblioteca requests (incluyendo llamadas a través de APIYI en apiyi.com), debes usar manualmente el formato camelCase (por ejemplo, inlineData, mimeType). De lo contrario, los campos serán ignorados y causarán un error.

P4: ¿Es este error el mismo que ‘contents.parts must not be empty’?

No exactamente, pero la causa es similar. contents.parts must not be empty ocurre cuando el arreglo parts está vacío ("parts": []). En cambio, required oneof field 'data' ocurre cuando parts contiene elementos, pero uno de esos elementos no tiene inicializado su campo de datos (por ejemplo, "parts": [{}]). La solución es la misma: asegúrate de que cada part contenga un text o inlineData válido.


Resumen

Los puntos clave del error required oneof field 'data' en el modelo de imágenes Gemini:

  1. Causa raíz: Existen objetos vacíos, datos vacíos o elementos con formato incorrecto en el array parts.
  2. Método de localización: Localizar directamente la posición correspondiente en el código según el número de índice parts[N] en el mensaje de error.
  3. Causas más comunes: Objeto vacío {}, base64 que contiene el prefijo data:, errores de mayúsculas/minúsculas en los nombres de los campos JSON.
  4. La API REST DEBE usar camelCase: inlineData (no inline_data), mimeType (no mime_type).
  5. Medidas preventivas: Agregar una función de validación del payload antes de enviar, para detectar automáticamente elementos vacíos y problemas de formato.

Se recomienda utilizar la plataforma APIYI apiyi.com para invocar el modelo de imágenes Gemini para desarrollo y depuración. Nano Banana 2 tiene un costo por uso de $0.045 por invocación, lo que resulta en un costo de depuración muy bajo, y su formato de interfaz es completamente compatible con la API REST oficial.


📚 Referencias

  1. Documentación oficial de generación de imágenes de la API Gemini: Formato de solicitud completo y explicación de parámetros.

    • Enlace: ai.google.dev/gemini-api/docs/image-generation
    • Descripción: Incluye el formato de solicitud estándar para Texto a Imagen e Imagen a Imagen.
  2. Guía de solución de problemas de la API Gemini: Códigos de error y sugerencias de reparación proporcionados oficialmente.

    • Enlace: ai.google.dev/gemini-api/docs/troubleshooting
    • Descripción: Cubre métodos de solución de problemas para errores comunes como 400, 429, 500, etc.
  3. GitHub Issue: Discusión sobre el error required oneof field data: Reporte de la comunidad y soluciones.

    • Enlace: github.com/google-gemini/cookbook/issues/786
    • Descripción: Incluye análisis detallado y workaround para este error causado por la transferencia de objetos File.
  4. Documentación de integración de APIYI Nano Banana 2: Guía completa para invocar el modelo de imágenes Gemini en la plataforma APIYI.

    • Enlace: docs.apiyi.com/en/api-capabilities/nano-banana-2-image
    • Descripción: Incluye ejemplos del formato de solicitud correcto y preguntas frecuentes.

Autor: Equipo técnico de APIYI
Intercambio técnico: Si encuentras problemas al invocar la API Gemini, visita el centro de documentación de APIYI en docs.apiyi.com para ver más guías de solución de problemas.

Publicaciones Similares