{"record":{"id":"7384607ed52276e5","repo":"VectifyAI/PageIndex","slug":"unsupported-role-for-chat-completions-role-r-t","errorCode":null,"errorMessage":"Unsupported role for chat_completions: {role!r}. Tool history round-trips belong to responses() or messages().","messagePattern":"Unsupported role for chat_completions: (.+?)\\. Tool history round-trips belong to responses\\(\\) or messages\\(\\)\\.","errorType":"exception","errorClass":"PageIndexAPIError","httpStatus":null,"severity":"error","filePath":"pageindex/local_chat.py","lineNumber":82,"sourceCode":"    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:\n            raise PageIndexAPIError(\n                f\"Unsupported role for chat_completions: {role!r}. Tool \"\n                \"history round-trips belong to responses() or messages().\"\n            )\n    if not history:\n        raise PageIndexAPIError(\"messages must contain a user or assistant \"\n                                \"message.\")\n    return system_texts, history\n\n\ndef _run_sync(coro):\n    from .utils import run_off_loop\n    return run_off_loop(asyncio.run, coro)\n\n\n_SENTINEL = object()\n\n\ndef _stream_sync(agen_factory) -> Iterator[Any]:","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/VectifyAI/PageIndex/blob/afb5e119766630af6014b04fe8b53357527bc05e/pageindex/local_chat.py#L64-L100","documentation":"chat_completions only accepts the roles system, developer, user, and assistant. Any other role — notably 'tool' — is rejected with the offending role echoed, because tool-history round-trips are handled by responses() or messages().","triggerScenarios":"messages containing {\"role\":\"tool\",\"content\":...} or a typo'd role like \"assitant\"/\"systemn\".","commonSituations":"Feeding full agent transcripts (which include tool results) back into chat_completions, role typos, converting between Anthropic and OpenAI role vocabularies (e.g. 'tool_result').","solutions":["Filter out non-supported roles before calling: keep only system/developer/user/assistant","Use responses() or messages() for transcripts with tool history","Check role strings against a whitelist when constructing messages"],"exampleFix":"# before\nclient.chat_completions(model=m, messages=full_transcript)\n\n# after\nmsgs=[m for m in full_transcript if m[\"role\"] in {\"system\",\"developer\",\"user\",\"assistant\"}]\nclient.chat_completions(model=m, messages=msgs)","handlingStrategy":"validation","validationCode":"ALLOWED = {'system','developer','user','assistant'}\nmessages = [m for m in messages if m.get('role') in ALLOWED]","typeGuard":"def is_supported_role(role) -> bool:\n    return role in {'system','developer','user','assistant'}","tryCatchPattern":"null","preventionTips":["Whitelist roles when constructing messages","Send tool transcripts through responses()/messages()","Lint for role typos in fixtures"],"tags":["pageindex","chat","role","validation","tool-history"],"backgroundTag":"unsupported-message-role","analyzedSha":"afb5e119766630af6014b04fe8b53357527bc05e","analyzedAt":"2026-08-27T11:20:48.519Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}