|

Résoudre l’erreur du modèle d’image Gemini ‘required oneof field data’ : 6 causes courantes et méthodes de correction

Note de l'auteur : Explication détaillée des 6 causes courantes et des solutions correspondantes pour l'erreur 400 required oneof field data must have one initialized field lors de l'appel des modèles d'image Gemini comme gemini-3.1-flash-image-preview.

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

Lors de l'appel de gemini-3.1-flash-image-preview (Nano Banana 2) ou gemini-3.0-pro-image (Nano Banana Pro) pour générer des images, de nombreux développeurs rencontrent cette erreur 400 déroutante :

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

La signification centrale de cette erreur est : Dans le corps de votre requête, le champ data d'un élément parts est vide ou mal formaté. L'erreur 400 est une erreur côté client (paramètres de requête incorrects) et ne se résoudra pas automatiquement. Vous devez corriger votre code.

Cet article répertorie les 6 causes courantes de cette erreur, chacune accompagnée d'une comparaison entre le code erroné et le code correct, pour vous aider à identifier et résoudre le problème rapidement.

Valeur principale : Après avoir lu cet article, vous pourrez localiser précisément la position du problème grâce à l'index parts[N] dans le message d'erreur, puis vérifier chacune des 6 causes. Généralement, le problème peut être résolu en moins de 5 minutes.


Analyse approfondie de l'erreur "required oneof field data" dans les modèles d'image Gemini

Point clé Explication Direction de dépannage
Nature de l'erreur Présence d'éléments vides ou mal formatés dans le tableau parts Vérifier chaque élément de contents[].parts[]
Indice crucial parts[2] fait référence au 3ème élément (indexation à partir de 0) Localiser directement la partie à l'index correspondant
Type d'erreur 400 INVALID_ARGUMENT, erreur côté client Ne se corrige pas automatiquement, nécessite une modification du code
Portée de l'impact Commun à tous les modèles d'image Gemini S'applique à NB2, NB Pro, Gemini Flash
Difficulté de correction Faible, généralement un problème de format Modifier en fonction du format correct

Interprétation de la structure du message d'erreur

Décomposons la structure du message d'erreur, c'est la clé pour localiser le problème :

GenerateContentRequest.contents[0].parts[2].data
                       ^^^^^^^^     ^^^^^^^^
                       │            │
                       │            └── 3ème part (indexation à partir de 0)
                       └── 1er bloc de contenu
  • contents[0] : Pointe vers le premier objet content de votre corps de requête
  • parts[2] : Pointe vers le 3ème élément part dans ce content
  • data : Le champ de données de cette part est vide ou n'est pas initialisé correctement

Approche de dépannage : Vérifiez directement dans votre code l'élément à l'index [2] du tableau parts du premier élément ([0]) du tableau contents pour voir ce qui est transmis.

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


6 causes courantes et méthodes de correction pour l'erreur des modèles d'image Gemini

Cause 1 : Présence d'objets vides ou de chaînes vides dans parts

C'est la cause la plus fréquente. Le tableau parts de la requête contient des éléments vides comme {}, null, des chaînes vides "", etc.

Écriture incorrecte Écriture correcte
parts contient un objet vide {} Chaque part doit avoir text ou inlineData
parts contient {"text": ""} Un texte vide déclenche aussi l'erreur, écrivez au moins un caractère
parts contient un élément null Supprimez toutes les valeurs null

Code incorrect :

# ❌ parts contient un objet vide
payload = {
    "contents": [{
        "parts": [
            {"text": "Générer une image de chat"},
            {},                              # ← Objet vide, déclenche l'erreur
            {"text": "dans un style aquarelle"}
        ]
    }]
}

Code correct :

# ✅ Chaque part a un contenu valide
payload = {
    "contents": [{
        "parts": [
            {"text": "Générer une image de chat dans un style aquarelle"}
        ]
    }]
}

Point de correction : Fusionnez le texte dans une seule part text, ou assurez-vous que chaque part contient un champ text ou inlineData valide.

Cause 2 : Données base64 de l'image vides ou mal formatées

Lorsque vous envoyez une requête image vers image, les données base64 dans inlineData peuvent être vides, corrompues ou mal formatées.

Code incorrect :

# ❌ Les données base64 contiennent le préfixe data URI
payload = {
    "contents": [{
        "parts": [
            {
                "inlineData": {
                    "mimeType": "image/png",
                    "data": "data:image/png;base64,iVBORw0KGgo..."  # ← Ne doit pas contenir le préfixe
                }
            },
            {"text": "Changer l'arrière-plan en bleu"}
        ]
    }]
}
# ❌ Les données base64 sont une chaîne vide
"inlineData": {
    "mimeType": "image/jpeg",
    "data": ""          # ← Données vides, déclenche directement l'erreur
}

Code correct :

import base64
import pathlib

# ✅ Lire correctement l'image et la convertir en base64 pur
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       # ← Chaîne base64 pure, sans préfixe
                }
            },
            {"text": "Changer l'arrière-plan en bleu"}
        ]
    }]
}

Points de correction :

  • Le champ data n'accepte que des chaînes base64 pures, sans le préfixe data:image/png;base64,
  • Assurez-vous que le fichier image existe bien et est lu avec succès, évitez de transmettre une chaîne vide
  • mimeType doit correspondre au format réel de l'image (image/png, image/jpeg, image/webp)

Cause 3 : L'objet File n'est pas correctement converti en référence de contenu

Après avoir téléchargé un fichier via l'API Files du SDK Google GenAI, le transmettre directement dans contents peut empêcher le SDK de le convertir correctement.

Code incorrect :

from google import genai

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

# Télécharger le fichier
file = client.files.upload(file="photo.png")

# ❌ Dans certaines versions du SDK, transmettre directement l'objet File échoue
response = client.models.generate_content(
    model="gemini-3.1-flash-image-preview",
    contents=["Modifier cette image", file]    # ← L'objet File peut ne pas être converti automatiquement
)

Code correct :

from google import genai
from google.genai import types

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

# Télécharger le fichier
file = client.files.upload(file="photo.png")

# ✅ Méthode 1 : Construire manuellement la référence au fichier
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="Modifier cette image : changer l'arrière-plan en coucher de soleil")
        ])
    ],
    config=types.GenerateContentConfig(
        response_modalities=["TEXT", "IMAGE"]
    )
)
# ✅ Méthode 2 : Utiliser inlineData pour transmettre directement le base64 (plus fiable)
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="Modifier cette image : changer l'arrière-plan en coucher de soleil")
        ])
    ],
    config=types.GenerateContentConfig(
        response_modalities=["TEXT", "IMAGE"]
    )
)

Point de correction : Il est recommandé d'utiliser la méthode inlineData + base64 pour transmettre directement les données de l'image, c'est plus stable et fiable que l'API Files.

Cause 4 : L'historique de conversation multi-tours contient du contenu vide

Lors de l'édition d'images dans une conversation multi-tours, si la réponse du tour précédent n'est pas traitée correctement, des blocs de contenu vides peuvent se glisser dans l'historique.

Code incorrect :

# ❌ L'historique de conversation contient des parts vides
history = [
    {"role": "user", "parts": [{"text": "Générer un logo"}]},
    {"role": "model", "parts": []},        # ← parts vide, déclenche l'erreur
    {"role": "user", "parts": [{"text": "Le rendre bleu"}]}
]

payload = {"contents": history}

Code correct :

# ✅ Filtrer les blocs de contenu vides
history = [
    {"role": "user", "parts": [{"text": "Générer un logo"}]},
    {"role": "model", "parts": [{"text": "Voici le logo que j'ai généré."}]},
    {"role": "user", "parts": [{"text": "Le rendre bleu"}]}
]

# Filtrage sécurisé : supprimer les enregistrements où parts est vide
clean_history = [msg for msg in history if msg.get("parts") and len(msg["parts"]) > 0]

payload = {"contents": clean_history}

Point de correction : Avant d'envoyer la requête, parcourez le tableau contents et filtrez tous les éléments dont parts est une liste vide ou contient des objets vides.

Cause 5 : Erreur de casse dans les noms de champs JSON de l'API REST

Les noms de champs JSON de l'API Gemini utilisent le camelCase (notation en casse de chameau) et sont sensibles à la casse. Une faute de frappe dans le nom du champ entraîne son ignorance, ce qui équivaut à transmettre des données vides.

Nom de champ incorrect Nom de champ correct Explication
inline_data inlineData L'API REST utilise camelCase
mime_type mimeType L'API REST utilise camelCase
file_uri fileUri L'API REST utilise camelCase
response_modalities responseModalities L'API REST utilise camelCase
image_config imageConfig L'API REST utilise camelCase
aspect_ratio aspectRatio L'API REST utilise camelCase
image_size imageSize L'API REST utilise camelCase

Code incorrect :

# ❌ Utilisation de snake_case (style Python SDK) dans l'API REST
payload = {
    "contents": [{
        "parts": [{
            "inline_data": {           # ← Devrait être inlineData
                "mime_type": "image/png",   # ← Devrait être mimeType
                "data": image_b64
            }
        }]
    }],
    "generation_config": {             # ← Devrait être generationConfig
        "response_modalities": ["IMAGE"]   # ← Devrait être responseModalities
    }
}

Code correct :

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

🎯 Rappel important : Le SDK Python (google-genai) utilise snake_case (comme inline_data), tandis qu'un appel direct à l'API REST utilise camelCase (comme inlineData). Lors d'un appel via une plateforme de proxy API comme APIYI apiyi.com, c'est le format de l'API REST qui est utilisé, il faut donc utiliser camelCase.

Cause 6 : Format d'image non pris en charge ou fichier corrompu

L'image transmise contient bien des données base64, mais le format de l'image n'est pas pris en charge ou le fichier est corrompu.

Formats d'entrée pris en charge par les modèles d'image Gemini :

Format mimeType État de support
PNG image/png Pris en charge
JPEG image/jpeg Pris en charge
WebP image/webp Pris en charge
GIF image/gif Pris en charge partiellement (seulement la première image)
BMP image/bmp Non pris en charge
SVG image/svg+xml Non pris en charge
TIFF image/tiff Non pris en charge

Méthode de vérification :

import base64

# Vérifier si les données base64 sont valides
def validate_image_data(b64_string, mime_type):
    # 1. Vérifier si la chaîne est vide
    if not b64_string:
        print("ERREUR : les données base64 sont vides")
        return False

    # 2. Vérifier si la chaîne contient le préfixe data URI
    if b64_string.startswith("data:"):
        print("ERREUR : Supprimez le préfixe 'data:image/...;base64,'")
        return False

    # 3. Vérifier si le base64 peut être décodé
    try:
        decoded = base64.b64decode(b64_string)
        print(f"OK : Taille décodée = {len(decoded)} octets")
    except Exception as e:
        print(f"ERREUR : Base64 invalide - {e}")
        return False

    # 4. Vérifier si le mimeType est pris en charge
    supported = ["image/png", "image/jpeg", "image/webp", "image/gif"]
    if mime_type not in supported:
        print(f"ERREUR : mimeType '{mime_type}' non pris en charge")
        return False

    print("VALIDÉ : Les données de l'image sont valides")
    return True

💡 Conseil : Ajoutez une fonction de validation des données avant d'envoyer la requête pour détecter la plupart des problèmes de format à l'avance. Cela s'applique également lors d'un appel via la plateforme APIYI apiyi.com.


Liste de vérification complète pour les erreurs du modèle d'image Gemini

Lorsque vous rencontrez l'erreur required oneof field 'data', suivez cette liste de vérification point par point :

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

Étape de vérification Contenu à vérifier Méthode de correction
Étape 1 Vérifier quel est l'index N dans parts[N] Localiser directement la position correspondante dans le code
Étape 2 Cet élément part est-il {}, null, "" ? Supprimer l'élément vide ou le remplir avec un contenu valide
Étape 3 S'il s'agit de inlineData, la chaîne base64 est-elle vide ? S'assurer que la lecture du fichier image a réussi
Étape 4 La chaîne base64 contient-elle le préfixe data: ? Supprimer le préfixe, ne conserver que le base64 pur
Étape 5 Le nom du champ JSON utilise-t-il camelCase ? L'API REST doit utiliser inlineData et non inline_data
Étape 6 Le format d'image est-il pris en charge ? Uniquement PNG/JPEG/WebP/GIF

Correction rapide : Si vous rencontrez fréquemment cette erreur pendant le développement, il est recommandé d'ajouter une fonction validate_payload() avant l'envoi de la requête, pour vérifier automatiquement si chaque élément du tableau parts est valide. Lorsque vous appelez le modèle d'image Gemini via la plateforme APIYI apiyi.com, le format de requête est entièrement compatible avec l'API REST officielle, et les méthodes de vérification ci-dessus s'appliquent également.


Erreurs courantes du modèle d'image Gemini et format de requête correct

Format correct pour le texte vers image (Text-to-Image)

import requests, base64

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

# ✅ Format minimal correct
payload = {
    "contents": [{
        "parts": [
            {"text": "Un mignon chat orange assis sur un rebord de fenêtre, style aquarelle, 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))

Format correct pour l'image vers image (Image-to-Image)

Voir le code complet correct pour l’image vers image
import requests
import base64
import pathlib

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

# Lire l'image source et la convertir en base64 pur
image_path = pathlib.Path("input_photo.png")
if not image_path.exists():
    raise FileNotFoundError(f"Image non trouvée : {image_path}")

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

# Valider les données
assert len(image_b64) > 0, "Les données base64 sont vides"
assert not image_b64.startswith("data:"), "Supprimez le préfixe data URI"

# ✅ Format de requête correct pour l'image vers image
payload = {
    "contents": [{
        "parts": [
            {
                "inlineData": {
                    "mimeType": "image/png",
                    "data": image_b64
                }
            },
            {
                "text": "Changez l'arrière-plan pour une scène de plage au coucher du soleil, gardez le sujet inchangé"
            }
        ]
    }],
    "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("Succès ! Image sauvegardée.")
else:
    print(f"Erreur {response.status_code} : {response.text}")

Conseil : Pour les scénarios texte vers image, commencez par le format le plus simple, assurez-vous qu'il fonctionne, puis ajoutez progressivement des paramètres. En passant par la plateforme APIYI apiyi.com pour appeler Nano Banana 2, le coût est de $0.045/requête, ce qui est très faible pendant la phase de débogage.


Questions fréquentes

Q1 : Que signifie `parts[2]` dans le message d’erreur ?

parts[2] fait référence à l'élément à l'index 2 du tableau parts, c'est-à-dire le troisième élément (l'index commence à 0). Localisez directement le troisième élément du tableau contents[0].parts dans votre code et vérifiez son contenu. Si votre tableau parts n'a que 2 éléments (index 0 et 1), cela signifie que la logique de votre code a peut-être ajouté par erreur un élément vide lors de la concaténation des parts.

Q2 : Cette erreur se produit-elle aussi lors d’un appel via APIYI ?

Oui. APIYI apiyi.com, en tant que service proxy API, transmet votre requête au backend Gemini. Si le corps de la requête présente un problème de format, le backend renverra la même erreur 400. APIYI ne modifie pas la structure de votre corps de requête, il est donc de la responsabilité du développeur de s'assurer que le format est correct. La bonne nouvelle est que la méthode de correction est exactement la même que pour un appel direct à l'API Google.

Q3 : Pourquoi les noms de champs diffèrent entre le SDK Python et l’API REST ?

Le SDK Python Google GenAI suit la convention de nommage snake_case de Python (par exemple inline_data, mime_type). Le SDK convertit automatiquement en interne vers le format camelCase requis par l'API. Cependant, si vous appelez directement l'API REST avec la bibliothèque requests (y compris via APIYI apiyi.com), vous devez manuellement utiliser le format camelCase (par exemple inlineData, mimeType). Sinon, les champs seront ignorés, ce qui provoquera une erreur.

Q4 : Cette erreur est-elle la même que `contents.parts must not be empty` ?

Pas exactement, mais la cause est similaire. contents.parts must not be empty signifie que le tableau parts est vide ("parts": []), tandis que required oneof field 'data' signifie que parts contient un élément, mais que le champ de données de cet élément n'est pas initialisé (par exemple "parts": [{}]). La logique de correction est la même : assurez-vous que chaque part contient un text ou un inlineData valide.


Résumé

Les points clés de l'erreur required oneof field 'data' du modèle d'image Gemini :

  1. Cause fondamentale : Présence d'objets vides, de données vides ou d'éléments mal formatés dans le tableau parts.
  2. Méthode de localisation : Localisez directement la position correspondante dans le code en utilisant l'index parts[N] indiqué dans le message d'erreur.
  3. Causes les plus courantes : Objet vide {}, base64 contenant le préfixe data:, erreur de casse dans les noms des champs JSON.
  4. L'API REST DOIT utiliser camelCase : inlineData (et non inline_data), mimeType (et non mime_type).
  5. Mesures préventives : Ajoutez une fonction de validation du payload avant l'envoi pour détecter automatiquement les éléments vides et les problèmes de format.

Il est recommandé d'utiliser la plateforme APIYI apiyi.com pour invoquer le modèle d'image Gemini lors du développement et du débogage. Nano Banana 2 est facturé à l'usage à 0,045 $ par invocation, ce qui réduit considérablement les coûts de débogage. Le format de l'interface est entièrement compatible avec l'API REST officielle.


📚 Références

  1. Documentation officielle de génération d'images Gemini API : Format de requête complet et description des paramètres.

    • Lien : ai.google.dev/gemini-api/docs/image-generation
    • Description : Contient le format de requête standard pour le texte vers image et l'image vers image.
  2. Guide de dépannage Gemini API : Codes d'erreur et suggestions de correction fournis par Google.

    • Lien : ai.google.dev/gemini-api/docs/troubleshooting
    • Description : Couvre les méthodes de dépannage pour les erreurs courantes comme 400, 429, 500.
  3. GitHub Issue : Discussion sur l'erreur required oneof field data : Rapport communautaire et solutions de contournement.

    • Lien : github.com/google-gemini/cookbook/issues/786
    • Description : Analyse détaillée et solution de contournement pour cette erreur causée par le passage d'objets File.
  4. Documentation d'intégration APIYI Nano Banana 2 : Guide complet pour invoquer le modèle d'image Gemini via la plateforme APIYI.

    • Lien : docs.apiyi.com/en/api-capabilities/nano-banana-2-image
    • Description : Contient des exemples de format de requête correct et des réponses aux questions fréquentes.

Auteur : Équipe technique APIYI
Échanges techniques : Si vous rencontrez des problèmes lors de l'appel de l'API Gemini, visitez le centre de documentation APIYI docs.apiyi.com pour plus de guides de dépannage.

Publications similaires