|

Resolvendo o erro “required oneof field data” do modelo de imagem Gemini: 6 causas comuns e métodos de correção

Nota do Autor: Explicação detalhada das 6 causas comuns e soluções correspondentes para o erro 400 "required oneof field data must have one initialized field" ao chamar modelos de imagem Gemini como gemini-3.1-flash-image-preview.

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

Ao chamar modelos como gemini-3.1-flash-image-preview (Nano Banana 2) ou gemini-3.0-pro-image (Nano Banana Pro) para gerar imagens, muitos desenvolvedores encontraram este erro 400 confuso:

{
  "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
  }
}

O significado central deste erro é: No corpo da sua requisição, o campo data de algum elemento parts está vazio ou em formato incorreto. O erro 400 é um erro de parâmetro do lado do cliente e não se resolve sozinho; você precisa corrigir o código.

Este artigo lista as 6 causas comuns que levam a este erro, cada uma acompanhada de uma comparação entre código errado e correto, para ajudá-lo a identificar e resolver o problema rapidamente.

Valor principal: Após ler este artigo, você poderá localizar com precisão a posição do problema usando o índice parts[N] na mensagem de erro e verificar uma por uma as 6 causas. Normalmente, você pode corrigir o problema em 5 minutos.


Análise do Erro "required oneof field data" nos Modelos de Imagem Gemini

Ponto Descrição Direção de Investigação
Natureza do Erro Existem elementos vazios ou mal formatados no array parts Verifique cada elemento em contents[].parts[]
Pista Crucial parts[2] indica o 3º elemento (contagem a partir de 0) Localize diretamente o part no índice correspondente
Tipo de Erro 400 INVALID_ARGUMENT, erro do cliente Não se recupera automaticamente, o código deve ser alterado
Escopo do Impacto Comum a todos os modelos de imagem Gemini Aplica-se a NB2, NB Pro, Gemini Flash
Dificuldade de Correção Baixa, geralmente é um problema de formatação Basta modificar conforme o formato correto

Interpretação da Estrutura da Mensagem de Erro do Modelo de Imagem Gemini

Vamos desmontar a estrutura da mensagem de erro, isso é crucial para localizar o problema:

GenerateContentRequest.contents[0].parts[2].data
                       ^^^^^^^^     ^^^^^^^^
                       │            │
                       │            └── 3º part (índice começa em 0)
                       └── 1º bloco de conteúdo (content)
  • contents[0]: Aponta para o primeiro objeto content no corpo da sua requisição.
  • parts[2]: Aponta para o terceiro elemento part dentro desse content.
  • data: O campo de dados desse part está vazio ou não foi inicializado corretamente.

Linha de raciocínio para investigação: Verifique diretamente no seu código o elemento parts[2] (índice 2) dentro do array parts do elemento contents[0] e veja o que foi passado.

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


6 Causas Comuns e Métodos de Correção para o Erro no Modelo de Imagem Gemini

Causa 1: Objeto vazio ou string vazia em parts

Esta é a causa mais comum. O array parts da requisição contém elementos vazios como {}, null, strings vazias "", etc.

Escrita Errada Escrita Correta
parts contém objeto vazio {} Cada part deve ter text ou inlineData
parts contém {"text": ""} Texto vazio também causa erro, escreva pelo menos um caractere
parts contém elemento null Remova todos os valores null

Código Errado:

# ❌ parts contém objeto vazio
payload = {
    "contents": [{
        "parts": [
            {"text": "Generate a cat image"},
            {},                              # ← Objeto vazio, causa erro
            {"text": "in watercolor style"}
        ]
    }]
}

Código Correto:

# ✅ Cada part tem conteúdo válido
payload = {
    "contents": [{
        "parts": [
            {"text": "Generate a cat image in watercolor style"}
        ]
    }]
}

Ponto de Correção: Combine o texto em um único text part, ou garanta que cada part contenha um campo text ou inlineData válido.

Causa 2: Dados base64 da imagem vazios ou mal formatados

Ao enviar uma requisição de imagem para imagem (image-to-image), os dados base64 em inlineData podem estar vazios, corrompidos ou formatados incorretamente.

Código Errado:

# ❌ Dados base64 contêm prefixo data URI
payload = {
    "contents": [{
        "parts": [
            {
                "inlineData": {
                    "mimeType": "image/png",
                    "data": "data:image/png;base64,iVBORw0KGgo..."  # ← Não deve conter prefixo
                }
            },
            {"text": "Change the background to blue"}
        ]
    }]
}
# ❌ Dados base64 são string vazia
"inlineData": {
    "mimeType": "image/jpeg",
    "data": ""          # ← Dados vazios, causa erro direto
}

Código Correto:

import base64
import pathlib

# ✅ Ler imagem corretamente e converter para 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       # ← String base64 pura, sem prefixo
                }
            },
            {"text": "Change the background to blue"}
        ]
    }]
}

Ponto de Correção:

  • O campo data aceita apenas strings base64 puras, não pode conter o prefixo data:image/png;base64,
  • Garanta que o arquivo de imagem exista e seja lido com sucesso, evitando passar strings vazias
  • mimeType deve corresponder ao formato real da imagem (image/png, image/jpeg, image/webp)

Causa 3: Objeto File não convertido corretamente para referência de conteúdo

Após fazer upload de um arquivo usando a Files API do SDK Google GenAI, passar o objeto File diretamente para contents pode fazer com que o SDK não o converta corretamente.

Código Errado:

from google import genai

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

# Fazer upload do arquivo
file = client.files.upload(file="photo.png")

# ❌ Em algumas versões do SDK, passar o objeto File diretamente falha
response = client.models.generate_content(
    model="gemini-3.1-flash-image-preview",
    contents=["Edit this image", file]    # ← Objeto File pode não ser convertido automaticamente
)

Código Correto:

from google import genai
from google.genai import types

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

# Fazer upload do arquivo
file = client.files.upload(file="photo.png")

# ✅ Método 1: Construir referência de arquivo manualmente
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="Edit this image: change background to sunset")
        ])
    ],
    config=types.GenerateContentConfig(
        response_modalities=["TEXT", "IMAGE"]
    )
)
# ✅ Método 2: Usar inlineData para passar base64 diretamente (mais confiável)
import base64, pathlib

image_b64 = base64.b64encode(pathlib.Path("photo.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="Edit this image: change background to sunset")
        ])
    ],
    config=types.GenerateContentConfig(
        response_modalities=["TEXT", "IMAGE"]
    )
)

Ponto de Correção: Recomenda-se usar o método inlineData + base64 para passar os dados da imagem diretamente, é mais estável e confiável que a Files API.

Causa 4: Histórico de conversa multirrodada contém conteúdo vazio

Ao editar imagens em uma conversa multirrodada, se a resposta da rodada anterior não for processada corretamente, o histórico pode conter blocos content vazios.

Código Errado:

# ❌ Histórico de conversa contém parts vazios
history = [
    {"role": "user", "parts": [{"text": "Generate a logo"}]},
    {"role": "model", "parts": []},        # ← parts vazio, causa erro
    {"role": "user", "parts": [{"text": "Make it blue"}]}
]

payload = {"contents": history}

Código Correto:

# ✅ Filtrar blocos de conteúdo vazios
history = [
    {"role": "user", "parts": [{"text": "Generate a logo"}]},
    {"role": "model", "parts": [{"text": "Here is the logo I generated."}]},
    {"role": "user", "parts": [{"text": "Make it blue"}]}
]

# Filtro seguro: remove registros onde parts está vazio
clean_history = [msg for msg in history if msg.get("parts") and len(msg["parts"]) > 0]

payload = {"contents": clean_history}

Ponto de Correção: Antes de enviar a requisição, percorra o array contents e filtre todos os elementos onde parts é uma lista vazia ou contém objetos vazios.

Causa 5: Erro de capitalização de nomes de campo JSON na API REST

Os nomes dos campos JSON na API Gemini usam camelCase (nomenclatura camel), que diferencia maiúsculas de minúsculas. Erros de digitação no nome do campo fazem com que ele seja ignorado, equivalente a passar dados vazios.

Nome de Campo Errado Nome de Campo Correto Explicação
inline_data inlineData API REST usa camelCase
mime_type mimeType API REST usa camelCase
file_uri fileUri API REST usa camelCase
response_modalities responseModalities API REST usa camelCase
image_config imageConfig API REST usa camelCase
aspect_ratio aspectRatio API REST usa camelCase
image_size imageSize API REST usa camelCase

Código Errado:

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

Código Correto:

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

🎯 Aviso de Confusão Comum: O Python SDK (google-genai) usa snake_case (como inline_data), enquanto a chamada direta à API REST usa camelCase (como inlineData). Ao chamar através de plataformas de proxy como APIYI apiyi.com, usa-se o formato da API REST, portanto deve-se usar camelCase.

Causa 6: Formato de imagem não suportado ou arquivo corrompido

A imagem passada tem dados base64, mas o formato em si não é suportado ou o arquivo está corrompido.

Formatos de entrada suportados pelos modelos de imagem Gemini:

Formato mimeType Status de Suporte
PNG image/png Suportado
JPEG image/jpeg Suportado
WebP image/webp Suportado
GIF image/gif Suporte parcial (apenas primeiro frame)
BMP image/bmp Não suportado
SVG image/svg+xml Não suportado
TIFF image/tiff Não suportado

Método de Investigação:

import base64

# Verificar se os dados base64 são válidos
def validate_image_data(b64_string, mime_type):
    # 1. Verificar se está vazio
    if not b64_string:
        print("ERRO: dados base64 estão vazios")
        return False

    # 2. Verificar se contém prefixo data URI
    if b64_string.startswith("data:"):
        print("ERRO: Remova o prefixo 'data:image/...;base64,'")
        return False

    # 3. Verificar se base64 pode ser decodificado
    try:
        decoded = base64.b64decode(b64_string)
        print(f"OK: Tamanho decodificado = {len(decoded)} bytes")
    except Exception as e:
        print(f"ERRO: Base64 inválido - {e}")
        return False

    # 4. Verificar se mimeType é suportado
    supported = ["image/png", "image/jpeg", "image/webp", "image/gif"]
    if mime_type not in supported:
        print(f"ERRO: mimeType '{mime_type}' não suportado")
        return False

    print("PASSOU: Dados da imagem são válidos")
    return True

💡 Sugestão: Adicionar uma função de validação de dados antes de enviar a requisição pode capturar a maioria dos problemas de formato antecipadamente. Aplica-se também ao chamar através da plataforma APIYI apiyi.com.


Lista Completa de Verificação para Erros no Modelo de Imagem Gemini

Quando você encontrar o erro required oneof field 'data', siga esta lista de verificação item por item:

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

Etapa de Verificação O que Verificar Método de Correção
Passo 1 Verifique em qual posição N está dentro do array parts Localize diretamente a posição correspondente no código
Passo 2 Verifique se essa parte está vazia ({}, null, "") Remova o elemento vazio ou preencha com conteúdo válido
Passo 3 Se for inlineData, verifique se o base64 está vazio Certifique-se de que o arquivo de imagem foi lido com sucesso
Passo 4 Verifique se o base64 contém o prefixo data: Remova o prefixo, mantenha apenas o base64 puro
Passo 5 Verifique se o nome do campo JSON está em camelCase A REST API exige inlineData, não inline_data
Passo 6 Verifique se o formato da imagem é suportado Apenas PNG/JPEG/WebP/GIF

Correção Rápida: Se você encontrar esse erro com frequência durante o desenvolvimento, recomendo adicionar uma função validate_payload() antes de enviar a requisição, para verificar automaticamente se cada elemento no array parts é válido. Ao chamar o modelo de imagem Gemini através da plataforma APIYI (apiyi.com), o formato da requisição é completamente compatível com a REST API oficial, portanto os métodos de verificação acima também se aplicam.


Formato correto de requisição para evitar erros no modelo de imagem Gemini

Formato correto para texto para imagem (Text-to-Image)

import requests, base64

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

# ✅ Formato correto mais simples
payload = {
    "contents": [{
        "parts": [
            {"text": "Um gato laranja fofo sentado no parapeito de uma janela, estilo aquarela, 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 correto para imagem para imagem (Image-to-Image)

Ver código completo correto para imagem para imagem
import requests
import base64
import pathlib

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

# Ler a imagem original e converter para base64 puro
image_path = pathlib.Path("input_photo.png")
if not image_path.exists():
    raise FileNotFoundError(f"Imagem não encontrada: {image_path}")

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

# Validar dados
assert len(image_b64) > 0, "Dados Base64 estão vazios"
assert not image_b64.startswith("data:"), "Remova o prefixo data URI"

# ✅ Formato de requisição correto para imagem para imagem
payload = {
    "contents": [{
        "parts": [
            {
                "inlineData": {
                    "mimeType": "image/png",
                    "data": image_b64
                }
            },
            {
                "text": "Altere o fundo para uma cena de praia ao pôr do sol, mantenha o sujeito inalterado"
            }
        ]
    }],
    "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("Sucesso! Imagem salva.")
else:
    print(f"Erro {response.status_code}: {response.text}")

Sugestão: Para cenários de texto para imagem, comece com o formato mais simples, confirme que funciona e depois adicione parâmetros gradualmente. Ao chamar o Nano Banana 2 pela plataforma APIYI apiyi.com, o custo é de $0,045 por chamada, tornando os custos da fase de depuração muito baixos.


Perguntas frequentes

Q1: O que significa parts[2] na mensagem de erro?

parts[2] se refere ao elemento no índice 2 do array parts, ou seja, o terceiro elemento (a indexação começa em 0). Localize diretamente no seu código o terceiro elemento do array contents[0].parts e verifique seu conteúdo. Se o seu array parts tiver apenas 2 elementos (índices 0 e 1), isso indica que a lógica do código pode ter adicionado acidentalmente um elemento vazio durante a montagem do array parts.

Q2: Esse erro também ocorre ao chamar pela APIYI?

Sim. A APIYI apiyi.com, como um serviço proxy de API, repassa sua requisição para o backend do Gemini. Se o corpo da requisição tiver problemas de formatação, o backend retornará o mesmo erro 400. A APIYI não modifica a estrutura do corpo da sua requisição, portanto, garantir que o formato da requisição esteja correto é responsabilidade do desenvolvedor. A boa notícia é que o método de correção é exatamente o mesmo que ao chamar a API do Google diretamente.

Q3: Por que os nomes dos campos são diferentes no Python SDK e na REST API?

O Google GenAI Python SDK segue a convenção de nomenclatura snake_case do Python (como inline_data, mime_type). O SDK converte internamente esses nomes para o camelCase exigido pela API. No entanto, se você usar a biblioteca requests para chamar a REST API diretamente (incluindo chamadas via APIYI apiyi.com), deve usar manualmente o formato camelCase (como inlineData, mimeType), caso contrário os campos serão ignorados, causando erro.

Q4: Esse erro é o mesmo que “contents.parts must not be empty”?

Não exatamente, mas a causa é semelhante. contents.parts must not be empty ocorre quando o array parts em si está vazio ("parts": []), enquanto required oneof field 'data' ocorre quando o array parts contém elementos, mas um desses elementos não tem o campo de dados inicializado (por exemplo, "parts": [{}]). A lógica de correção é a mesma: certifique-se de que cada part contenha um text ou inlineData válido.


Resumo

Os pontos principais do erro required oneof field 'data' no modelo de imagem Gemini:

  1. Causa raiz: Existem objetos vazios, dados vazios ou elementos com formato incorreto no array parts.
  2. Método de localização: Localize diretamente a posição correspondente no código usando o número do índice parts[N] na mensagem de erro.
  3. Causas mais comuns: Objeto vazio {}, base64 contendo o prefixo data:, erro de maiúsculas/minúsculas no nome do campo JSON.
  4. A API REST DEVE usar camelCase: inlineData (não inline_data), mimeType (não mime_type).
  5. Medidas preventivas: Adicione uma função de validação do payload antes do envio para detectar automaticamente elementos vazios e problemas de formato.

Recomendamos usar a plataforma APIYI apiyi.com para chamar o modelo de imagem Gemini para desenvolvimento e depuração. O Nano Banana 2 tem cobrança por uso de $0,045 por chamada, custo de depuração muito baixo, e o formato da interface é totalmente compatível com a API REST oficial.


📚 Referências

  1. Documentação oficial de geração de imagem da API Gemini: Formato de requisição completo e especificação de parâmetros.

    • Link: ai.google.dev/gemini-api/docs/image-generation
    • Descrição: Inclui o formato de requisição padrão para Texto para Imagem e Imagem para Imagem.
  2. Guia de solução de problemas da API Gemini: Códigos de erro e sugestões de correção fornecidos oficialmente.

    • Link: ai.google.dev/gemini-api/docs/troubleshooting
    • Descrição: Abrange métodos de solução de problemas para erros comuns como 400, 429, 500, etc.
  3. GitHub Issue: Discussão sobre o erro required oneof field data: Relatos da comunidade e soluções alternativas.

    • Link: github.com/google-gemini/cookbook/issues/786
    • Descrição: Inclui análise detalhada e workaround para este erro causado pela passagem de objetos File.
  4. Documentação de integração do Nano Banana 2 da APIYI: Guia completo para chamar o modelo de imagem Gemini na plataforma APIYI.

    • Link: docs.apiyi.com/en/api-capabilities/nano-banana-2-image
    • Descrição: Inclui exemplos do formato de requisição correto e perguntas frequentes.

Autor: Equipe Técnica da APIYI
Comunidade técnica: Encontrou problemas ao chamar a API Gemini? Visite o centro de documentação da APIYI em docs.apiyi.com para ver mais guias de solução de problemas.

Similar Posts