BerriAI/litellm · error · TextCompletionCodestralError

response.text

Error message

response.text

What it means

In the streaming text-completion path for Codestral, make_call posts to the API with stream=True and checks the status code before consuming the body. Any non-200 response (401 unauthorized, 422 malformed request, 429 rate limit, 5xx) is converted into a TextCompletionCodestralError whose message is the raw response body text. This happens during stream setup, before any chunk is yielded.

Source

Thrown at litellm/llms/codestral/completion/handler.py:62

            self.response = response
        else:
            self.response = httpx.Response(status_code=status_code, request=self.request)
        super().__init__(self.message)  # Call the base class constructor with the parameters it needs


async def make_call(
    client: AsyncHTTPHandler,
    api_base: str,
    headers: dict,
    data: str,
    model: str,
    messages: list,
    logging_obj,
):
    response: Final = await client.post(api_base, headers=headers, data=data, stream=True)

    if response.status_code != 200:
        raise TextCompletionCodestralError(status_code=response.status_code, message=response.text)

    completion_stream: Final = response.aiter_lines()
    # LOGGING
    logging_obj.post_call(
        input=messages,
        api_key="",
        original_response=completion_stream,  # Pass the completion stream for logging
        additional_args={"complete_input_dict": data},
    )

    return completion_stream


class CodestralTextCompletion:
    def __init__(self) -> None:
        super().__init__()

    def _validate_environment(

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Inspect the raised TextCompletionCodestralError.status_code and .message: the message is the raw body from Mistral and names the real cause.
  2. 401/403: refresh CODESTRAL_API_KEY with a valid Mistral/Codestral key.
  3. 429: add retry with exponential backoff (e.g. litellm's num_retries or tenacity) and reduce request rate.
  4. 400/422: validate the payload — model name must be a FIM model (codestral-latest), prompt formatted as text completion, max_tokens within limits.
  5. 5xx: retry with backoff; check status.mistral.ai.
Defensive patterns

Strategy: retry

Try / catch

from litellm.exceptions import TextCompletionCodestralError

try:
    stream = litellm.text_completion(
        model="text-completion-codestral/codestral-latest", prompt=p, stream=True
    )
    for tok in stream:
        ...
except TextCompletionCodestralError as e:
    if e.status_code in (429, 500, 502, 503):
        backoff_and_retry()  # transient
    else:
        raise  # 401/422 are permanent: fix key/payload

Prevention

When it happens

Trigger: Calling Codestral text completion (api.mistral.ai/v1/fim/completions style, via the codestral text-completion handler) in streaming mode when the API returns any non-200 status: expired API key (401), bad request payload (400/422), rate limiting (429), or upstream outage (5xx).

Common situations: Expired or revoked CODESTRAL_API_KEY; switching between the Codestral beta endpoint and GA endpoint with an incompatible model name; exceeding Mistral rate limits under load; passing a context longer than the model limit.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/f5359d8bc58dc354. Report an issue: GitHub.