sgl-project/sglang · error · ValueError

`task` requires at least one message with role='user' or 'de

Error message

`task` requires at least one message with role='user' or 'developer'.

What it means

attach_task_to_last_user_message needs an existing user/developer message to attach the task to; find_last_user_index returned -1, so ValueError is raised.

Source

Thrown at python/sglang/srt/entrypoints/openai/encoding_dsv4.py:254

        thinking_end_token=thinking_end_token,
    )


def find_last_user_index(messages: List[Dict[str, Any]]) -> int:
    """Find the index of the last user/developer message."""
    last_user_index = -1
    for idx in range(len(messages) - 1, -1, -1):
        if messages[idx].get("role") in ["user", "developer"]:
            last_user_index = idx
            break
    return last_user_index


def attach_task_to_last_user_message(messages: List[Dict[str, Any]], task: str) -> None:
    """Set `task` on the most recent user/developer message; raise if none exists."""
    idx = find_last_user_index(messages)
    if idx == -1:
        raise ValueError(
            "`task` requires at least one message with role='user' or 'developer'."
        )
    messages[idx]["task"] = task


# ============================================================
# Message Rendering
# ============================================================


def render_message(
    index: int,
    messages: List[Dict[str, Any]],
    thinking_mode: str,
    drop_thinking: bool = True,
    reasoning_effort: Optional[str] = None,
    reasoning_effort_profile: str = "preview",
) -> str:

View on GitHub (pinned to 0132848349)

Solutions

  1. Include at least one message with role 'user' or 'developer' in the request.
  2. Or drop the `task` field if no user message is intended.
  3. Ensure the task is not attached after history truncation removed the user turn.

Example fix

# before
messages=[{"role":"assistant","content":"..."}], extra_body={"task":"summarize"}
# after
messages=[{"role":"user","content":"doc..."},{"role":"assistant","content":"..."}], extra_body={"task":"summarize"}
Defensive patterns

Strategy: validation

Validate before calling

if task and not any(m['role'] in ('user','developer') for m in messages):
    messages.insert(0,{'role':'user','content':task})

Prevention

When it happens

Trigger: Passing a `task` extra in a chat completion request whose messages contain only assistant/system/tool roles.

Common situations: Sending a task instruction with an assistant-prefill-only conversation; programmatic message builders that omit the user turn when a task is set.

Related errors


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