{"record":{"id":"c812255cdfd8432d","repo":"microsoft/graphrag","slug":"invalid-role-value","errorCode":null,"errorMessage":"Invalid Role: {value}","messagePattern":"Invalid Role: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"packages/graphrag/graphrag/query/context_builder/conversation_history.py","lineNumber":37,"sourceCode":"class ConversationRole(str, Enum):\n    \"\"\"Enum for conversation roles.\"\"\"\n\n    SYSTEM = \"system\"\n    USER = \"user\"\n    ASSISTANT = \"assistant\"\n\n    @staticmethod\n    def from_string(value: str) -> \"ConversationRole\":\n        \"\"\"Convert string to ConversationRole.\"\"\"\n        if value == \"system\":\n            return ConversationRole.SYSTEM\n        if value == \"user\":\n            return ConversationRole.USER\n        if value == \"assistant\":\n            return ConversationRole.ASSISTANT\n\n        msg = f\"Invalid Role: {value}\"\n        raise ValueError(msg)\n\n    def __str__(self) -> str:\n        \"\"\"Return string representation of the enum value.\"\"\"\n        return self.value\n\n\n\"\"\"\nData class for storing a single conversation turn\n\"\"\"\n\n\n@dataclass\nclass ConversationTurn:\n    \"\"\"Data class for storing a single conversation turn.\"\"\"\n\n    role: ConversationRole\n    content: str\n","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/microsoft/graphrag/blob/f40e9a26ce62ba0b3fef8837d24aafdcc6e6c704/packages/graphrag/graphrag/query/context_builder/conversation_history.py#L19-L55","documentation":"ConversationRole.from_string only accepts the exact lowercase strings 'user' and 'assistant'. Any other value (including 'USER', 'system', 'tool', or None) raises ValueError with the offending value. This is strict enum parsing for LLM conversation history in GraphRAG queries.","triggerScenarios":"Calling ConversationHistory.from_list / from_string with messages whose 'role' field isn't exactly 'user' or 'assistant' — e.g. role='System', role='system', role=None, or a typo like 'asistant'.","commonSituations":"Feeding OpenAI-style chat history containing 'system' or 'tool' roles; loading stored conversation JSON where roles were capitalized or localized; hand-built history dicts in notebooks.","solutions":["Normalize roles to lowercase 'user'/'assistant' before calling from_list","Filter out or remap non-chat roles (system/tool/function) to 'user' or drop them","Inspect the offending message with a quick print to see the exact bad value in the error"],"exampleFix":"# before\nhistory = ConversationHistory.from_list([{'role': 'System', 'content': '...'}])\n# after\nmsgs = [{'role': m['role'].lower(), 'content': m['content']}\n        for m in raw if m['role'].lower() in ('user', 'assistant')]\nhistory = ConversationHistory.from_list(msgs)","handlingStrategy":"validation","validationCode":"VALID = {'user', 'assistant'}\nmsgs = [m for m in raw if str(m.get('role', '')).lower() in VALID]\nhistory = ConversationHistory.from_list(msgs)","typeGuard":"def is_valid_role(r: object) -> bool:\n    return isinstance(r, str) and r.lower() in ('user', 'assistant')","tryCatchPattern":"try:\n    history = ConversationHistory.from_list(msgs)\nexcept ValueError as e:\n    logger.warning('dropping bad role: %s', e)\n    history = ConversationHistory()","preventionTips":["Normalize roles to lowercase before building history","Map or drop system/tool roles from imported chat transcripts"],"tags":["graphrag","conversation-history","enum-parsing","validation"],"backgroundTag":"enum-value-invalid","analyzedSha":"f40e9a26ce62ba0b3fef8837d24aafdcc6e6c704","analyzedAt":"2026-08-27T11:16:29.677Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}