BerriAI/litellm · error · Exception
kwarg `messages` must be an array of messages that follow…
Error message
kwarg `messages` must be an array of messages that follow the openai chat standard
What it means
Bytez's validate_environment raises this generic Exception when the messages kwarg is empty (falsy). It is a request-shape guard: Bytez needs at least one message to build the chat request. Note it fires before the api_key check in the same method, so an empty-messages call reports this rather than the missing-key error.
Solutions
- Ensure at least one message, typically a user turn, before calling: guard with `if not messages: append fallback`.
- Fix the upstream slicing/filtering that emptied the list.
- Add a unit test on your prompt builder asserting non-empty messages.
Example fix
# before
messages = [m for m in history if keep(m)] # can become []
litellm.completion(model="bytez/...", messages=messages)
# after
messages = [m for m in history if keep(m)] or [{"role": "user", "content": "Hello"}]
litellm.completion(model="bytez/...", messages=messages) Defensive patterns
Strategy: validation
Validate before calling
def has_messages(messages) -> bool:
return isinstance(messages, list) and len(messages) > 0
assert has_messages(messages), "refusing to call bytez with empty messages" Type guard
from typing import Any
def is_nonempty_message_list(messages: Any) -> bool:
return (
isinstance(messages, list)
and len(messages) > 0
and all(isinstance(m, dict) and m.get("role") and "content" in m for m in messages)
) Try / catch
try:
litellm.completion(model="bytez/org/model", messages=messages)
except Exception as e:
if "messages" in str(e) and not messages:
messages = [{"role": "user", "content": "Hello"}]
litellm.completion(model="bytez/org/model", messages=messages)
else:
raise Prevention
- Guard prompt builders: return a fallback user message instead of an empty list.
- Assert non-empty messages in tests of your chat pipeline.
When it happens
Trigger: litellm.completion(model="bytez/...", messages=[]) or messages=None; templates/chat-history slicing that accidentally yields an empty list (e.g., trimming context too aggressively); passing conversation history that failed to populate from a DB.
Common situations: Dynamic prompt builders trimming history to zero turns; early-exit branches that still call the LLM; None default leaking through instead of a user message.
Related errors
- Prop `type` is not a string
- Prop ` ` is not a string
- `content` can only contain strings or openai content dicts
- Invalid first message. Should always start with…
- Invalid image URL
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/12f9aec9f80d3005.
Report an issue: GitHub.
Appendix: 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 77b7c6c40c)