zylon-ai/private-gpt · error · ValueError
Messages cannot be empty
Error message
Messages cannot be empty
What it means
ChatBody's pydantic model_validator rejects a request whose messages list is empty or missing. Every chat completion needs at least one message; the validator normalizes out-of-range sampling params first, then hard-fails on structural problems, returning HTTP 422 (pydantic ValidationError) to the API caller.
Source
Thrown at private_gpt/server/chat/chat_models.py:313
self.temperature = None
if self.repetition_penalty and self.repetition_penalty < 0:
self.repetition_penalty = None
if self.presence_penalty and self.presence_penalty < 0:
self.presence_penalty = None
if self.frequency_penalty and self.frequency_penalty < 0:
self.frequency_penalty = None
if self.seed and self.seed < 0:
self.seed = None
if self.max_tokens is not None and self.max_tokens <= 0:
self.max_tokens = None
if not self.messages:
raise ValueError("Messages cannot be empty")
for message in self.messages:
if not message.content:
raise ValueError(f"Message content cannot be empty: {message}")
if isinstance(message.content, list):
for block in message.content:
if block is None:
raise ValueError(f"Block cannot be None: {message}")
if self.messages[-1].role not in self._valid_last_message_roles:
raise ValueError(
f"Last message role must be one of {self._valid_last_message_roles}, but got {self.messages[-1].role}"
)
# Check tools and tool choice
if self.tools and self.tool_choice and self.tool_choice.type == "tool":
if not self.tools:
raise ValueError("Tool choice is set, but no tools are provided.")View on GitHub (pinned to 4a030776a3)
Solutions
- Ensure the client always sends at least one message, e.g. {"role":"user","content":"..."}.
- Guard in the UI: disable the send action until the conversation has content.
- If you operate the server, map pydantic ValidationError to a clean 422 response so the caller sees which field failed.
Example fix
# before
curl -X POST /v1/chat/completions -d '{"model":"x","messages":[]}'
# after
curl -X POST /v1/chat/completions -d '{"model":"x","messages":[{"role":"user","content":"hello"}]}' Defensive patterns
Strategy: validation
Validate before calling
def valid_messages(msgs: list) -> bool:
return bool(msgs) and all(m.get('content') for m in msgs) Type guard
def has_messages(body: dict) -> bool:
ms = body.get('messages')
return isinstance(ms, list) and len(ms) > 0 Try / catch
try:
resp = client.chat.completions.create(**body)
except ValidationError as e:
if 'Messages cannot be empty' in str(e):
raise UserInputError('Type a message before sending') from e
raise Prevention
- Disable the send button until user input exists
- Assert message list non-empty in request-builder unit tests
- Map pydantic ValidationError to friendly 422s server-side
When it happens
Trigger: POSTing to /v1/chat/completions with "messages": [] or omitting the field; a client bug that filters out all messages before sending; a proxy or test harness sending an empty conversation.
Common situations: Frontend builds the request from an empty chat state and sends it on mount; message-sanitizing middleware strips every message; scripted clients replaying truncated fixtures.
Related errors
- Message content cannot be empty: {message}
- Invalid system item in list (dict): {item}
- 'oneOf' must be an array of schemas
- 'anyOf' must be an array of schemas
- 'allOf' must be an array of schemas
AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15).
Data as JSON: /api/errors/57d8ab16c8daa624.
Report an issue: GitHub.