Retour aux guides
Dépannage·28 août 2026·6 min de lecture

Gemini API 400 INVALID_ARGUMENT — « please use a valid role » et la famille empty-contents

Presque toutes les erreurs INVALID_ARGUMENT de cette forme proviennent de l’envoi de messages au format OpenAI vers le point de terminaison natif generateContent de Google. Les noms de rôles sont différents, les instructions système disposent d’un emplacement distinct et un tour vide n’est pas toléré.

Dernière vérification le .

Presque toutes les erreurs INVALID_ARGUMENT de cette forme proviennent de l’envoi de messages au format OpenAI vers le point de terminaison natif generateContent de Google. Les noms de rôles sont différents, les instructions système disposent d’un emplacement distinct et un tour vide n’est pas toléré.

L’erreur

two members of the same family (HTTP 400)
{"error":{"code":400,
  "message":"Please use a valid role: user, model.",
  "status":"INVALID_ARGUMENT"}}

{"error":{"code":400,
  "message":"* GenerateContentRequest.contents: contents is not specified\n",
  "status":"INVALID_ARGUMENT"}}

Causes et solutions en bref

CauseSolution
Messages au format OpenAI envoyés au point de terminaison natifassistant → model, et system devient systemInstruction. Rien d’autre n’est autorisé.
Tableau contents videTous les messages ont été filtrés — souvent un tour d’outil avec content: null.
Un tour avec un tableau parts videRemplacez-le par une partie de texte vide au lieu d’émettre un tour sans partie.
Données d’image intégrées sans mimeTypeinline_data nécessite à la fois mime_type et les données base64.

Déterminez d’abord quelle API vous utilisez réellement

Le même nom de SDK masque deux schémas incompatibles : le generateContent natif de Google, qui accepte contents avec les rôles user et model, et un /v1/chat/completions compatible OpenAI, qui accepte messages avec system, user et assistant. Toutes les erreurs de cette famille proviennent d’un contenu préparé pour une API puis envoyé à l’autre.

Convertissez les rôles si vous utilisez l’API native

Les messages system et developer sont regroupés dans un champ systemInstruction distinct. assistant devient model. user reste user. Tout autre rôle n’a pas d’équivalent et doit être supprimé ou fusionné avant l’envoi.

to_gemini.py
def to_gemini(messages):
    system, contents = [], []
    for m in messages:
        if m["role"] in ("system", "developer"):
            system.append(m["content"])
            continue
        if m["role"] not in ("user", "assistant"):
            continue  # no Gemini equivalent
        parts = [{"text": m["content"] or ""}]  # never emit empty parts
        contents.append({
            "role": "model" if m["role"] == "assistant" else "user",
            "parts": parts,
        })
    req = {"contents": contents}
    if system:
        req["systemInstruction"] = {"parts": [{"text": "\n\n".join(system)}]}
    return req

N’émettez jamais un tour sans partie

Un message dont le contenu est null ou qui a été entièrement filtré produit un tour sans partie, qui est rejeté. Remplacer celui-ci par une partie de texte vide maintient la validité du tour et préserve l’alternance attendue par le modèle.

Validez avant l’envoi

Vérifiez que contents n’est pas vide, que chaque rôle est user ou model et que chaque tour contient au moins une partie. Trois lignes au point d’appel, plutôt qu’une erreur 400 renvoyée par le réseau.

Si vous appelez via Kunavo

Appeler Gemini via le /v1/chat/completions compatible OpenAI de Kunavo vous évite de construire vous-même le tableau contents de Google : vous envoyez des messages au format OpenAI et la passerelle effectue la conversion — les messages system et developer sont regroupés dans systemInstruction, assistant est converti en model, les rôles sans équivalent sont supprimés et une partie de texte vide est substituée au lieu d’émettre un tour sans partie. Cette catégorie entière d’erreurs INVALID_ARGUMENT ne provient donc pas de la structure des messages. En revanche, elle ne peut pas vous protéger contre un argument réellement invalide — par exemple un response_format non pris en charge ou une image intégrée mal formée — qui sera toujours rejeté pour ce motif. Les tarifs par token pour la gamme Gemini sont indiqués dans notre guide des tarifs Gemini.

Questions fréquentes

Quels sont les rôles valides de Gemini ?

Sur l’API native, exactement deux : user et model. Il n’existe pas de rôle system ; les instructions système vont dans le champ systemInstruction distinct.

Puis-je envoyer un message système ?

Pas comme un tour. Déplacez-le dans systemInstruction ou utilisez un point de terminaison compatible OpenAI qui s’en charge pour vous.

Pourquoi le même contenu fonctionne-t-il avec OpenAI ?

Parce que le schéma d’OpenAI définit les rôles system et assistant, contrairement au schéma natif de Gemini. Le contenu est valide — pour l’autre API.

Guides associés

La sémantique détaillée des erreurs est disponible dans référence des erreurs ; obtenir une clé prend une minute via inscription et la guide d’authentification.