Quasi tutti gli errori INVALID_ARGUMENT di questo tipo derivano dall'invio di messaggi in stile OpenAI all'endpoint nativo generateContent di Google. Ha nomi dei ruoli diversi, uno spazio separato per le istruzioni di sistema e non tollera un turno vuoto.
L’errore
{"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"}}Cause e soluzioni in breve
| Causa | Soluzione |
|---|---|
| Messaggi in stile OpenAI inviati all'endpoint nativo | assistant → model, e system viene spostato in systemInstruction. Nient'altro è valido. |
| Array contents vuoto | Ogni messaggio è stato filtrato — spesso si tratta di un turno dello strumento con content: null. |
| Un turno con un array parts vuoto | Sostituisci un part di testo vuoto invece di emettere un turno privo di parts. |
| Dati di immagine inline senza mimeType | inline_data richiede sia mime_type sia dati base64. |
Determina quale API stai effettivamente utilizzando
Lo stesso nome SDK fa da interfaccia a due schemi incompatibili: generateContent nativo di Google, che usa contents con i ruoli user e model, e /v1/chat/completions compatibile con OpenAI, che usa messages con system, user e assistant. Ogni errore di questa famiglia deriva da un payload scritto per una API e inviato all'altra.
Mappa i ruoli se stai usando quella nativa
I messaggi system e developer confluiscono in un campo systemInstruction separato. assistant diventa model. user resta user. Qualsiasi altro ruolo non ha un equivalente e deve essere eliminato o unito prima dell'invio.
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 reqNon emettere mai un turno privo di parts
Un messaggio il cui content era null o è stato filtrato completamente produce un turno senza parts, che viene rifiutato. Sostituirlo con un part di testo vuoto mantiene valido il turno e preserva l'alternanza prevista dal modello.
Convalida prima dell'invio
Verifica che contents non sia vuoto, che ogni ruolo sia user o model e che ogni turno abbia almeno un part. Tre righe nel punto della chiamata, invece di un 400 dalla rete.
Se chiami tramite Kunavo
Chiamare Gemini tramite /v1/chat/completions compatibile con OpenAI di Kunavo significa non dover costruire manualmente l'array contents di Google: invii messaggi in stile OpenAI e il gateway esegue la mappatura — i messaggi system e developer confluiscono in systemInstruction, assistant viene riscritto come model, i ruoli senza equivalente vengono eliminati e viene sostituito un part di testo vuoto invece di emettere un turno privo di parts. Pertanto questa intera classe di INVALID_ARGUMENT non deriva dalla struttura dei messaggi. Ciò da cui non può proteggerti è un argomento realmente non valido — un response_format non supportato o un'immagine inline malformata — che verrà comunque rifiutato in base al suo contenuto. Le tariffe per token della gamma Gemini sono disponibili in la nostra guida ai prezzi Gemini.
Domande frequenti
Quali sono i ruoli validi di Gemini?
Nell'API nativa, esattamente due: user e model. Non esiste il ruolo system: le istruzioni di sistema vanno nel campo separato systemInstruction.
Posso inviare un messaggio di sistema?
Non come turno. Spostalo in systemInstruction oppure usa un endpoint compatibile con OpenAI che lo faccia per te.
Perché lo stesso payload funziona con OpenAI?
Perché lo schema OpenAI definisce i ruoli system e assistant, mentre lo schema nativo di Gemini no. Il payload è valido, ma per l'altra API.
Guide correlate
- Gemini API 429 RESOURCE_EXHAUSTED — quota o limite di frequenza, risolto correttamente
- La chiave API Gemini non funziona — API_KEY_INVALID e le sue cinque cause
Ulteriori dettagli sul significato degli errori sono disponibili in riferimento agli errori; ottenere una chiave richiede un minuto tramite registrazione e la guida all’autenticazione.