BerriAI/litellm · error · AzureOpenAIError

Missing model or messages

Error message

Missing model or messages

What it means

The Azure text-completion handler validates that both model and messages are non-None before building the request, raising AzureOpenAIError 422 otherwise. The OpenAI-style API fundamentally requires a model identifier and a prompt source, and LiteLLM derives the prompt from messages via prompt_factory.

Source

Thrown at litellm/llms/azure/completion/handler.py:53

        api_key: str | None,
        api_base: str,
        api_version: str,
        api_type: str,
        azure_ad_token: str | None,
        azure_ad_token_provider: Callable | None,
        print_verbose: Callable,
        timeout,
        logging_obj: LiteLLMLoggingObj,
        optional_params,
        litellm_params: dict[str, object],
        logger_fn,
        acompletion: bool = False,
        headers: dict | None = None,
        client=None,
    ):
        try:
            if model is None or messages is None:
                raise AzureOpenAIError(status_code=422, message="Missing model or messages")

            max_retries: Final = optional_params.pop("max_retries", 2)
            prompt: Final = prompt_factory(messages=messages, model=model, custom_llm_provider="azure_text")

            ### CHECK IF CLOUDFLARE AI GATEWAY ###
            ### if so - set the model as part of the base url
            if api_base is not None and "gateway.ai.cloudflare.com" in api_base:
                ## build base url - assume api base includes resource name
                client = self._init_azure_client_for_cloudflare_ai_gateway(
                    api_key=api_key,
                    api_version=api_version,
                    api_base=api_base,
                    model=model,
                    client=client,
                    max_retries=max_retries,
                    timeout=timeout,
                    azure_ad_token=azure_ad_token,
                    azure_ad_token_provider=azure_ad_token_provider,

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Ensure both model and messages are provided: litellm.text_completion(model="azure/<deployment>", prompt="hello", ...).
  2. Validate the request payload at your API boundary (require model + messages/prompt fields) before it reaches LiteLLM.
  3. If calling the class directly, pass every positional/keyword argument the signature expects rather than relying on defaults.

Example fix

# before
resp = azure_text_llm.completion(messages=None, model=None, ...)

# after
resp = azure_text_llm.completion(
    model="azure/my-text-deployment",
    messages=[{"role": "user", "content": "hello"}],
    ...,
)
Defensive patterns

Strategy: validation

Validate before calling

def validate_completion_request(payload: dict) -> None:
    if not payload.get("model") or not payload.get("messages"):
        raise RequestValidationError("'model' and 'messages' are required")

Type guard

from typing import TypeGuard

def has_model_and_messages(d: dict) -> TypeGuard[dict]:
    return isinstance(d.get("model"), str) and isinstance(d.get("messages"), list) and len(d["messages"]) > 0

Try / catch

try:
    resp = litellm.text_completion(model=model, prompt=p, ...)
except AzureOpenAIError as e:
    if e.status_code == 422 and "Missing model or messages" in str(e):
        return bad_request_response()  # 400 to your caller
    raise

Prevention

When it happens

Trigger: Calling AzureOpenAITextCompletion.completion() directly (or via litellm.text_completion with the azure provider) with model=None or messages=None; upstream code building the call from unvalidated user input where fields can be missing.

Common situations: Dynamic dispatch code that maps request dicts to completion calls and passes missing keys; refactors renaming messages to prompt; API servers forwarding partial payloads without schema validation.

Related errors


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