BerriAI/litellm · error · AzureOpenAIError

Missing model or messages

Error message

Missing model or messages

What it means

This 422 from the Azure OpenAI chat completion path fires when `model` or `messages` is None at call time. It is a defensive check at the top of the completion handler before any client is constructed. In normal usage LiteLLM's router fills these from your request, so hitting it usually means a programmatic caller passed None explicitly.

Source

Thrown at litellm/llms/azure/azure.py:220

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

            max_retries = optional_params.pop("max_retries", None)
            if max_retries is None:
                max_retries = DEFAULT_MAX_RETRIES
            json_mode: Final[bool | None] = optional_params.pop("json_mode", False)

            ### 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:
                client = self._init_azure_client_for_cloudflare_ai_gateway(
                    api_base=api_base,
                    model=model,
                    api_version=api_version,
                    max_retries=max_retries,
                    timeout=timeout,
                    api_key=api_key,
                    azure_ad_token=azure_ad_token,
                    azure_ad_token_provider=azure_ad_token_provider,

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Check the call site: log the exact model and messages values right before the LiteLLM call.
  2. Default or fail fast on missing values in your own resolution logic instead of passing None.
  3. If you call litellm.completion, ensure the first positional model argument is a non-empty string and messages is a non-empty list.

Example fix

# before
model = config.get('model')  # may be None
resp = litellm.completion(model=model, messages=msg_list, custom_llm_provider='azure')

# after
model = config.get('model')
if not model:
    raise ValueError('config["model"] is missing')
resp = litellm.completion(model=model, messages=msg_list, custom_llm_provider='azure')
Defensive patterns

Strategy: validation

Validate before calling

assert isinstance(model, str) and model, 'model must be a non-empty string'
assert isinstance(messages, list) and messages, 'messages must be a non-empty list'

Prevention

When it happens

Trigger: Calling the internal AzureOpenAI completion function directly with model=None or messages=None; a custom provider wrapper or mocked router that forwards unset values; dynamic model resolution code that returns None and is passed through unchecked.

Common situations: Building the model string from config/env and the lookup silently failing to None; refactors that renamed parameters and left a stale kwarg; test fixtures that omit messages.

Related errors


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