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

  1. Normalize roles to lowercase 'user'/'assistant' before calling from_list
  2. Filter out or remap non-chat roles (system/tool/function) to 'user' or drop them
  3. 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

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


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)