microsoft/graphrag · error · ValueError
Invalid Role: {value}
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.
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)
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.
Related errors
- request_id needs to be passed as a keyword argument
- k must be an integer > 0
- Invalid EntityVectorStoreKey: {value}
- Column name is None
- list item is not [{item_type}]: {v} ({type(v)})
AI-assisted analysis of microsoft/graphrag@f40e9a26ce (2026-08-27).
Data as JSON: /api/errors/c812255cdfd8432d.
Report an issue: GitHub.