{"record":{"id":"a315f1fb9a70d6b3","repo":"VectifyAI/PageIndex","slug":"system-message-content-must-be-a-string-or-a-list","errorCode":null,"errorMessage":"system message content must be a string or a list of text parts.","messagePattern":"system message content must be a string or a list of text parts\\.","errorType":"exception","errorClass":"PageIndexAPIError","httpStatus":null,"severity":"error","filePath":"pageindex/local_chat.py","lineNumber":53,"sourceCode":"        raise PageIndexAPIError(\"doc_id must be a string or a list of \"\n                                \"strings.\")\n    # scoped: local surfaces also pass doc_id into the tool layer, so name\n    # resolution happens inside the allowlist — only a duplicate name\n    # within the targeted set shadows. Cloud tools take no allowlist\n    # (targeting is prompt-level), so the whole library shadows.\n    return doc_targeting_block(client, doc_id, scoped=scoped)\n\n\ndef _system_text(content: Any) -> str:\n    \"\"\"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\"):","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/VectifyAI/PageIndex/blob/afb5e119766630af6014b04fe8b53357527bc05e/pageindex/local_chat.py#L35-L71","documentation":"When building the managed system prompt, system/developer message content must be either a string or a list of parts each containing a 'text' key with a string value. Content that is a list with no valid text parts (e.g. only image parts, empty list, or parts whose text is not a string) raises this error.","triggerScenarios":"Passing a system message with content=[{\"type\":\"image_url\",...}], content=[], or content=[{\"text\": 123}] to chat_completions.","commonSituations":"Forwarding raw OpenAI/Anthropic request bodies where system content is multimodal, constructing messages from templating code that emits non-string text, copying examples with content-part arrays.","solutions":["Use a plain string for system/developer content","Extract only text parts and join them before passing","If you need multimodal system content, move it to the user turn or use responses()/messages()"],"exampleFix":"# before\nmessages=[{\"role\":\"system\",\"content\":[{\"type\":\"text\",\"text\": 42}]}]\n\n# after\nmessages=[{\"role\":\"system\",\"content\":\"You are a helpful assistant.\"}]","handlingStrategy":"type-guard","validationCode":"for m in messages:\n    if m['role'] in ('system','developer'):\n        m['content'] = m['content'] if isinstance(m['content'], str) else \"\\n\".join(p['text'] for p in m['content'] if isinstance(p, dict) and isinstance(p.get('text'), str))","typeGuard":"def has_valid_system_content(content) -> bool:\n    if isinstance(content, str): return True\n    return isinstance(content, list) and any(isinstance(p, dict) and isinstance(p.get('text'), str) for p in content)","tryCatchPattern":"null","preventionTips":["Use plain strings for system prompts","Don't forward multimodal system content from other SDKs","Extract text parts when adapting request bodies"],"tags":["pageindex","chat","system-message","validation"],"backgroundTag":"message-content-format-invalid","analyzedSha":"afb5e119766630af6014b04fe8b53357527bc05e","analyzedAt":"2026-08-27T11:20:48.519Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}