{"record":{"id":"685dc57de982eb4d","repo":"VectifyAI/PageIndex","slug":"messages-must-be-a-non-empty-list","errorCode":null,"errorMessage":"messages must be a non-empty list.","messagePattern":"messages must be a non-empty list\\.","errorType":"exception","errorClass":"PageIndexAPIError","httpStatus":null,"severity":"error","filePath":"pageindex/local_chat.py","lineNumber":63,"sourceCode":"    \"\"\"Text of a system/developer message: a string, or text parts joined.\"\"\"\n    if isinstance(content, str):\n        return content\n    if isinstance(content, list):\n        texts = [part.get(\"text\") for part in content\n                 if isinstance(part, dict) and isinstance(part.get(\"text\"), str)]\n        if texts:\n            return \"\\n\".join(texts)\n    raise PageIndexAPIError(\n        \"system message content must be a string or a list of text parts.\"\n    )\n\n\ndef _split_chat_messages(messages) -> \"tuple[list[str], list[dict]]\":\n    \"\"\"Validate the chat_completions surface's messages: system/developer\n    content joins the managed instructions; user/assistant history passes\n    through. Tool-history round-trips belong to responses()/messages().\"\"\"\n    if not isinstance(messages, list) or not messages:\n        raise PageIndexAPIError(\"messages must be a non-empty list.\")\n    system_texts: list[str] = []\n    history: list[dict] = []\n    for message in messages:\n        if not isinstance(message, dict) or \"role\" not in message:\n            raise PageIndexAPIError(\n                \"Each message must be a dict with 'role' and 'content'.\")\n        role = message[\"role\"]\n        if role in (\"system\", \"developer\"):\n            system_texts.append(_system_text(message.get(\"content\")))\n        elif role in (\"user\", \"assistant\"):\n            content = message.get(\"content\")\n            if not isinstance(content, str):\n                raise PageIndexAPIError(\n                    \"chat_completions content must be a string; for \"\n                    \"structured items use responses() or messages().\"\n                )\n            history.append({\"role\": role, \"content\": content})\n        else:","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/VectifyAI/PageIndex/blob/afb5e119766630af6014b04fe8b53357527bc05e/pageindex/local_chat.py#L45-L81","documentation":"chat_completions requires messages to be a non-empty Python list. None, a string, a dict, or an empty list all fail this upfront validation before any model call.","triggerScenarios":"Calling chat_completions(messages=[]), messages=None, or messages=\"hello\" (string shortcut unsupported here).","commonSituations":"Template code producing empty history on first turn, passing a JSON-decoded value that turned out to be an object, forgetting to include the user's message after building system prompt.","solutions":["Ensure the list has at least one message, typically the user turn","Guard: if not messages: append a default user message or return early","Parse-then-validate external payloads before calling"],"exampleFix":"# before\nclient.chat_completions(model=m, messages=history or [])\n\n# after\nif not history:\n    raise ValueError(\"conversation history is empty\")\nclient.chat_completions(model=m, messages=history)","handlingStrategy":"validation","validationCode":"assert isinstance(messages, list) and messages, 'messages must be a non-empty list'","typeGuard":"def is_valid_messages(msgs) -> bool:\n    return isinstance(msgs, list) and len(msgs) > 0","tryCatchPattern":"null","preventionTips":["Check history non-empty before calling","Default to a user message when templates render empty","Reject empty conversation at your API boundary"],"tags":["pageindex","chat","messages","validation"],"backgroundTag":"empty-messages-array","analyzedSha":"afb5e119766630af6014b04fe8b53357527bc05e","analyzedAt":"2026-08-27T11:20:48.519Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}