sgl-project/sglang · error · NotImplementedError

Unknown role: {role}

Error message

Unknown role: {role}

What it means

render_message hit a message role it cannot handle. DSv32 supports a fixed set (user/system/developer/tool/assistant); anything else raises NotImplementedError.

Source

Thrown at python/sglang/srt/entrypoints/openai/encoding_dsv32.py:291

        summary_content = content or ""

        if thinking_mode == "thinking" and index > last_user_idx:
            if not (reasoning_content or tool_calls):
                raise DS32EncodingError(
                    f"ThinkingMode: {thinking_mode}, invalid message without reasoning_content/tool_calls `{msg}` after last user message"
                )
            thinking_part = (
                thinking_template.format(reasoning_content=reasoning_content or "")
                + thinking_end_token
            )

        prompt += assistant_msg_template.format(
            reasoning=thinking_part,
            content=summary_content,
            tool_calls=tool_calls_content,
        )
    else:
        raise NotImplementedError(f"Unknown role: {role}")

    return prompt


def drop_thinking_messages(
    messages: List[Dict[str, Any]], last_user_idx: Optional[int] = None
) -> List[Dict[str, Any]]:
    messages_wo_thinking: List[Dict[str, Any]] = []
    last_user_idx = (
        find_last_user_index(messages) if last_user_idx is None else last_user_idx
    )
    for idx, msg in enumerate(messages):
        role = msg.get("role")
        if role in ["user", "system", "tool"] or idx >= last_user_idx:
            messages_wo_thinking.append(msg)
            continue

        elif role == "assistant":

View on GitHub (pinned to 0132848349)

Solutions

  1. Fix the role string to one of the supported roles.
  2. Convert legacy 'function' role messages to 'tool' with tool_call_id.
  3. Upgrade sglang if the role is newly supported.

Example fix

# before
{"role":"function","content":"42"}
# after
{"role":"tool","tool_call_id":"1","content":"42"}
Defensive patterns

Strategy: type-guard

Validate before calling

ALLOWED={'user','system','developer','assistant','tool'}
assert all(m['role'] in ALLOWED for m in messages)

Type guard

def is_known_role(r): return r in {'user','system','developer','assistant','tool'}

Prevention

When it happens

Trigger: A message with role like 'function', 'latest_reminder', or a typo ('assistent') in the messages array.

Common situations: Porting OpenAI 'function' call transcripts; typos in role strings; new role names not supported by this encoder version.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/23c4ef19d3701d3b. Report an issue: GitHub.