Fix Mistral AI 422 Unprocessable Entity: MistralAPIStatusException on Bad API Parameters

intermediate🧠 AI Tools2026-07-04| Python 3.8+, mistralai SDK 0.x / 1.x, Linux / macOS / Windows

Error Message

mistralai.exceptions.MistralAPIStatusException
#mistral-ai#python#api#422#llm#ai-tools#mistralai-sdk

TL;DR

A mistralai.exceptions.MistralAPIStatusException with HTTP 422 is a parameter validation failure, not a network or auth problem. The Mistral API parsed your JSON fine β€” it just rejected what was inside it. Common culprits: wrong model name, temperature above 1.0, an invalid message role, or a field like frequency_penalty that Mistral doesn't support. Find the bad parameter in the detail field and fix it.

What the error looks like

mistralai.exceptions.MistralAPIStatusException: Status: 422. Message: {"message": "Invalid request", "detail": [{"loc": ["body", "temperature"], "msg": "value is not a valid float", "type": "value_error.number.not_lt"}]}

The mistralai SDK wraps every non-2xx HTTP response in a MistralAPIStatusException. HTTP 422 means Unprocessable Entity β€” the server parsed your request successfully but the contents failed validation. This is always a bug in your code. Not a network issue, not an outage, not an auth problem. The response body tells you exactly what went wrong.

Root causes

  • Model name typo or unsupported model β€” e.g. "mistral-gpt-4" or "mistral-large" (must include the version suffix, like -latest)
  • Temperature out of range β€” Mistral accepts 0.0–1.0; passing 1.5 or 2 triggers 422
  • Invalid message role β€” only "user", "assistant", "system", and "tool" are valid
  • Wrong type for a parameter β€” e.g. passing max_tokens as a string "500" instead of int 500
  • Unsupported extra fields β€” OpenAI-specific parameters like frequency_penalty and presence_penalty don't exist in Mistral's API
  • Empty or malformed messages list β€” no messages at all, or a message missing the content key

Step 1 β€” Read the detail field

Before guessing, read the error. Every 422 response includes a detail array that pinpoints the exact field and explains why it failed. Catch the exception and print it:

import mistralai

try:
    response = client.chat.complete(model=model, messages=messages, temperature=temp)
except mistralai.exceptions.MistralAPIStatusException as e:
    print("Status:", e.http_status)
    print("Body:", e.message)   # contains the raw JSON detail
    raise

In the output, loc points to the bad field β€” e.g. ["body", "temperature"] β€” and msg tells you what rule it broke. Start here. Don't guess.

Step 2 β€” Validate model name

Model IDs are case-sensitive and require an exact version suffix. "mistral-large" fails; "mistral-large-latest" works. Pull the current list from the API to see what your account can actually use:

from mistralai import Mistral

client = Mistral(api_key="your-api-key")
models = client.models.list()
for m in models.data:
    print(m.id)

Pick one of the returned IDs β€” mistral-large-latest, mistral-small-latest, open-mistral-7b, etc. Don't invent names.

Step 3 β€” Fix parameter ranges

Mistral enforces strict types and value ranges. Here's what each parameter accepts:

  • temperature: float between 0.0 and 1.0 (inclusive)
  • top_p: float between 0.0 and 1.0
  • max_tokens: positive integer, not exceeding the model's context window
  • random_seed: integer, not a float
response = client.chat.complete(
    model="mistral-large-latest",
    messages=[
        {"role": "user", "content": "Hello"}
    ],
    temperature=0.7,      # float 0.0–1.0, NOT 1.5 or 2
    top_p=0.9,
    max_tokens=512,       # int, NOT "512"
    random_seed=42,       # int if set
)

Step 4 β€” Validate the messages array

Every message needs two keys: role and content. The role must be one of exactly four values β€” anything else triggers 422.

# Wrong β€” will trigger 422
messages = [
    {"role": "human", "content": "Hi"},   # invalid role
    {"role": "ai", "text": "Hello"},       # wrong key + wrong role
    {"role": "user"},                       # missing content
]

# Correct
messages = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "What is 2+2?"},
    {"role": "assistant", "content": "4"},
    {"role": "user", "content": "And 3+3?"},
]

One more thing: an empty messages=[] always fails. You need at least one message.

Step 5 β€” Remove unknown parameters

Migrating from OpenAI? Several OpenAI parameters don't exist in Mistral's API and will cause 422 if you pass them:

# Parameters that exist in OpenAI but NOT in Mistral (will cause 422)
# frequency_penalty, presence_penalty, logit_bias, logprobs, n

# Safe Mistral chat.complete() parameters (as of SDK v1.x)
response = client.chat.complete(
    model="mistral-small-latest",
    messages=messages,
    temperature=0.7,
    top_p=1.0,
    max_tokens=1024,
    stream=False,
    safe_prompt=False,
    random_seed=None,
)

Step 6 β€” SDK version mismatch

The mistralai SDK had a breaking API change between 0.x and 1.x. The old call was client.chat(); the new one is client.chat.complete(). Use the wrong pattern and you get AttributeError. Pass old-style keyword arguments to the new client and you get 422.

# Check your installed version
pip show mistralai

# Upgrade to latest stable
pip install --upgrade mistralai

If you must stay on 0.x, use the 0.x call pattern:

# mistralai 0.x
from mistralai.client import MistralClient
from mistralai.models.chat_completion import ChatMessage

client = MistralClient(api_key="your-api-key")
response = client.chat(
    model="mistral-small",
    messages=[ChatMessage(role="user", content="Hello")],
)

Verification

Run this quick smoke test once you've made your fix. No exception means you're good:

from mistralai import Mistral

client = Mistral(api_key="your-api-key")
response = client.chat.complete(
    model="mistral-small-latest",
    messages=[{"role": "user", "content": "Say OK"}],
    temperature=0.5,
    max_tokens=10,
)
print(response.choices[0].message.content)  # Should print: OK

Quick reference β€” valid vs invalid

# INVALID β†’ 422
client.chat.complete(
    model="mistral-large",          # missing -latest or version suffix
    messages=[],                     # empty list
    temperature=2.0,                 # out of range
    max_tokens="1000",               # string instead of int
    frequency_penalty=0.5,           # unsupported parameter
)

# VALID
client.chat.complete(
    model="mistral-large-latest",
    messages=[{"role": "user", "content": "Hello"}],
    temperature=0.7,
    max_tokens=1000,
)

Further reading

Related Error Notes