BerriAI/litellm · error · Exception

kwarg `messages` must be an array of messages that follow th

Error message

kwarg `messages` must be an array of messages that follow the openai chat standard

What it means

Bytez's validate_environment asserts that the messages list is non-empty before building headers; an empty (or None) messages list raises this Exception. It is a client-side precondition mirroring the OpenAI chat contract, raised before any HTTP request is made.

Source

Thrown at litellm/llms/bytez/chat/transformation.py:135

        self,
        headers: dict,
        model: str,
        messages: list[AllMessageValues],
        optional_params: dict,
        litellm_params: dict,
        api_key: str | None = None,
        api_base: str | None = None,
    ) -> dict:
        headers.update(
            {
                "content-type": "application/json",
                "Authorization": f"Key {api_key}",
                "user-agent": f"litellm/{version}",
            }
        )

        if not messages:
            raise Exception("kwarg `messages` must be an array of messages that follow the openai chat standard")

        if not api_key:
            raise Exception("Missing api_key, make sure you pass in your api key")

        return headers

    def get_complete_url(
        self,
        api_base: str | None,
        api_key: str | None,
        model: str,
        optional_params: dict,
        litellm_params: dict,
        stream: bool | None = None,
    ) -> str:
        encoded_model: Final = encode_url_path_segments(model, field_name="model")
        return f"{API_BASE}/{encoded_model}"

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Check messages is a non-empty list before calling and skip/short-circuit empty conversations.
  2. Ensure at least one user message exists by construction in your chat loop.
  3. Log the input right before the call to find where the empty list originates.

Example fix

# before
resp = litellm.completion(model=model, messages=session.get("messages", []))

# after
msgs = session.get("messages", [])
if not msgs:
    return "Please say something first."
resp = litellm.completion(model=model, messages=msgs)
Defensive patterns

Strategy: validation

Validate before calling

if not isinstance(messages, list) or len(messages) == 0:
    raise ValueError("messages must be a non-empty list before calling the model")

Type guard

def has_messages(messages: object) -> bool:
    return isinstance(messages, list) and len(messages) > 0 and all(
        isinstance(m, dict) and m.get("role") and m.get("content") is not None for m in messages
    )

Try / catch

try:
    litellm.completion(model="bytez/...", messages=msgs)
except Exception as e:
    if "must be an array of messages" in str(e):
        msgs = msgs or [{"role": "user", "content": fallback_prompt}]
        litellm.completion(model="bytez/...", messages=msgs)
    else:
        raise

Prevention

When it happens

Trigger: litellm.completion(model="bytez/...", messages=[]) or messages=None — typically from dynamic conversation builders that produce an empty history (e.g. trimmed context, empty user input).

Common situations: Chat apps that trim messages aggressively until none remain; feeding an empty list when a user submits blank input; data pipelines batching conversations where some conversations are empty.

Related errors


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