VectifyAI/PageIndex · error · PageIndexAPIError
messages must be a non-empty string or a list of message dic
Error message
messages must be a non-empty string or a list of message dicts.
What it means
run_messages() normalizes its input: a non-blank string becomes a single user message, otherwise messages must be a non-empty list of dicts. This guard fires before any network traffic when the input is neither — e.g. an empty string, empty list, a list containing non-dicts, or a bare dict/tuple.
Source
Thrown at pageindex/local_chat.py:1029
top_p: Optional[float] = None,
top_k: Optional[int] = None,
stop_sequences: Optional[list[str]] = None,
max_turns: Optional[int] = None,
thinking: Optional[dict] = None,
extra_body: Optional[dict] = None,
extra_headers: Optional[dict] = None,
backend: Optional[dict] = None,
) -> Union[dict, Iterator[Any]]:
from .integrations.anthropic_sdk import build_anthropic_tools
_require_anthropic()
import anthropic
_validate_max_turns(max_turns)
if isinstance(messages, str) and messages.strip():
messages = [{"role": "user", "content": messages}]
if (not isinstance(messages, list) or not messages
or not all(isinstance(message, dict) for message in messages)):
raise PageIndexAPIError("messages must be a non-empty string or a "
"list of message dicts.")
scope = client._local_doc_scope(doc_id)
block = _doc_block(client, doc_id, scoped=scope is not None)
prepared = [dict(message) for message in messages]
passthrough = {key: value for key, value in {
"temperature": temperature, "top_p": top_p, "top_k": top_k,
"stop_sequences": stop_sequences, "thinking": thinking,
"extra_body": extra_body, "extra_headers": extra_headers,
}.items() if value is not None}
system_blocks = _anthropic_system(client, system, block)
# Top-level cache_control: the server re-marks the newest block each
# turn, so the loop re-reads the growing conversation from cache.
# Counts toward the 4-breakpoint limit (live-verified 400 past it).
cached: dict[str, Any] = (
{"cache_control": {"type": "ephemeral"}}
if _cache_marks(system_blocks, prepared) < 4 else {})
# Tools before the transport: on a bridge client building them is
# network I/O, and a failure there must not strand the client below.View on GitHub (pinned to afb5e11976)
Solutions
- Ensure messages is a non-empty string or a list of dicts like [{'role': 'user', 'content': '...'}]
- Filter/validate upstream user input before calling messages()
- If the list may be empty, skip the call entirely (there is nothing to send)
Example fix
# before
client.messages(user_input) # user_input may be ""
# after
if isinstance(user_input, str) and user_input.strip():
client.messages(user_input) Defensive patterns
Strategy: validation
Validate before calling
def valid_messages(msgs) -> bool:
if isinstance(msgs, str):
return bool(msgs.strip())
return (isinstance(msgs, list) and bool(msgs)
and all(isinstance(m, dict) for m in msgs))
if not valid_messages(user_msgs):
return # nothing to send Type guard
def is_message_list(v) -> bool:
return (isinstance(v, list) and len(v) > 0
and all(isinstance(m, dict) and 'role' in m and 'content' in m for m in v)) Prevention
- Guard blank user input before calling messages()
- Wrap single blocks/messages in the documented dict shape
When it happens
Trigger: client.messages(""), client.messages([]), client.messages(["hello"]) (list of strings), or client.messages(None) — any input that is not a non-blank string or a list of message dicts.
Common situations: Forwarding user input that can be empty (a blank chat box); passing [{'role': 'user', 'content': ...}, 'extra'] by accident; template bugs producing None.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- messages must be a non-empty list.
- Each message must be a dict with 'role' and 'content'.
- messages must contain a user or assistant message.
- system must be a string or a list of blocks.
- limit must be between 1 and 100
AI-assisted analysis of VectifyAI/PageIndex@afb5e11976 (2026-08-27).
Data as JSON: /api/errors/e05ad3bac8264ba3.
Report an issue: GitHub.