microsoft/graphrag · error · ValueError
Invalid Role
Error message
Invalid Role: {value} What it means
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.
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
Example fix
# before
history = ConversationHistory.from_list([{'role': 'System', 'content': '...'}])
# after
msgs = [{'role': m['role'].lower(), 'content': m['content']}
for m in raw if m['role'].lower() in ('user', 'assistant')]
history = ConversationHistory.from_list(msgs) Defensive patterns
Strategy: validation
Validate before calling
VALID = {'user', 'assistant'}
msgs = [m for m in raw if str(m.get('role', '')).lower() in VALID]
history = ConversationHistory.from_list(msgs) Type guard
def is_valid_role(r: object) -> bool:
return isinstance(r, str) and r.lower() in ('user', 'assistant') Try / catch
try:
history = ConversationHistory.from_list(msgs)
except ValueError as e:
logger.warning('dropping bad role: %s', e)
history = ConversationHistory() Prevention
- Normalize roles to lowercase before building history
- Map or drop system/tool roles from imported chat transcripts
When it happens
Trigger: 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'.
Common situations: 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.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Column name is None
- Invalid EntityVectorStoreKey
- k must be an integer > 0
- list item is not [ ]: ( )
- request_id needs to be passed as a keyword argument
AI-assisted analysis of microsoft/graphrag@f40e9a26ce (2026-08-27).
Data as JSON: /api/errors/c812255cdfd8432d.
Report an issue: GitHub.
Appendix: source
Thrown at packages/graphrag/graphrag/query/context_builder/conversation_history.py:37
class ConversationRole(str, Enum):
"""Enum for conversation roles."""
SYSTEM = "system"
USER = "user"
ASSISTANT = "assistant"
@staticmethod
def from_string(value: str) -> "ConversationRole":
"""Convert string to ConversationRole."""
if value == "system":
return ConversationRole.SYSTEM
if value == "user":
return ConversationRole.USER
if value == "assistant":
return ConversationRole.ASSISTANT
msg = f"Invalid Role: {value}"
raise ValueError(msg)
def __str__(self) -> str:
"""Return string representation of the enum value."""
return self.value
"""
Data class for storing a single conversation turn
"""
@dataclass
class ConversationTurn:
"""Data class for storing a single conversation turn."""
role: ConversationRole
content: str
View on GitHub (pinned to f40e9a26ce)