BerriAI/litellm · error · ValueError

Bad Request: messages is required for Anthropic Messages Req

Error message

Bad Request: messages is required for Anthropic Messages Request

What it means

Same adapter validation path as the 'model' check, but for the second required field: 'messages'. The Anthropic Messages API mandates a non-empty messages array, and this handler enforces it client-side by popping 'messages' from kwargs and rejecting falsy values before constructing the typed request.

Source

Thrown at litellm/llms/anthropic/experimental_pass_through/adapters/transformation.py:171

        Translate Anthropic request params to OpenAI format, returning tool name mapping.

        This method handles truncation of tool names that exceed OpenAI's 64-character
        limit. The mapping allows restoring original names when translating responses.

        Returns:
            Tuple of (openai_request, tool_name_mapping)
            - tool_name_mapping maps truncated tool names back to original names
        """

        #########################################################
        # Validate required params
        #########################################################
        model: Final = kwargs.pop("model")
        messages: Final = kwargs.pop("messages")
        if not model:
            raise ValueError("Bad Request: model is required for Anthropic Messages Request")
        if not messages:
            raise ValueError("Bad Request: messages is required for Anthropic Messages Request")

        #########################################################
        # Created Typed Request Body
        #########################################################
        request_body: Final = AnthropicMessagesRequest(model=model, messages=messages, **kwargs)

        (
            translated_body,
            tool_name_mapping,
        ) = LiteLLMAnthropicMessagesAdapter().translate_anthropic_to_openai(anthropic_message_request=request_body)

        return translated_body, tool_name_mapping

    def translate_completion_output_params(
        self,
        response: ModelResponse,
        tool_name_mapping: dict[str, str] | None = None,
        polyfill_result: PolyfillResult | None = None,

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Include a non-empty 'messages' array, e.g. [{"role": "user", "content": "hello"}], in the request body.
  2. If the caller only has a prompt string, wrap it: messages=[{"role": "user", "content": prompt}].
  3. Guard upstream: reject requests with empty messages before they reach the adapter.

Example fix

# before
kwargs = {"model": "claude-sonnet-4-5", "max_tokens": 100}
handler(**kwargs)  # ValueError: messages is required

# after
kwargs = {
    "model": "claude-sonnet-4-5",
    "max_tokens": 100,
    "messages": [{"role": "user", "content": "hello"}],
}
handler(**kwargs)
Defensive patterns

Strategy: validation

Validate before calling

def validate_messages(body: dict) -> None:
    msgs = body.get("messages")
    if not isinstance(msgs, list) or len(msgs) == 0:
        raise ValueError("request body must include a non-empty 'messages' array")

Type guard

def has_valid_messages(body: dict) -> bool:
    msgs = body.get("messages")
    return isinstance(msgs, list) and len(msgs) > 0 and all(
        isinstance(m, dict) and "role" in m and "content" in m for m in msgs
    )

Try / catch

try:
    handler(**body)
except ValueError as e:
    if "messages is required" in str(e):
        return http_error(400, "messages is required")
    raise

Prevention

When it happens

Trigger: Calling the adapter handler with kwargs missing 'messages', messages=None, or messages=[] (empty list is falsy and also rejected). Common when a caller strips messages for logging/middleware or builds the body from a template that omits them.

Common situations: Proxy middleware that deserializes and re-serializes bodies and drops 'messages' on empty payloads; agent frameworks that call the completion path with only a prompt string instead of messages; empty-list edge cases in tests.

Related errors


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