sgl-project/sglang · error · ValueError

Assistant tool call function.arguments must be a JSON object

Error message

Assistant tool call function.arguments must be a JSON object.

What it means

parse_tool_call_arguments requires the parsed arguments to be a JSON object (dict), not an array, string, or number. Tool arguments map parameter names to values, so scalars/lists are rejected after successful JSON parsing.

Source

Thrown at python/sglang/srt/entrypoints/openai/serving_chat.py:137

        for p in parts
    )
    if is_openai_text_parts:
        text_parts = [p.get("text", "") if isinstance(p, dict) else p for p in parts]
        return " ".join(text_parts)
    return content


def parse_tool_call_arguments(arguments: str) -> Dict[str, Any]:
    """Parse OpenAI tool call arguments for chat templates."""
    try:
        parsed_arguments = orjson.loads(arguments)
    except orjson.JSONDecodeError as exc:
        raise ValueError(
            "Assistant tool call function.arguments must be valid JSON."
        ) from exc

    if not isinstance(parsed_arguments, dict):
        raise ValueError(
            "Assistant tool call function.arguments must be a JSON object."
        )

    return parsed_arguments


def normalize_assistant_tool_call_arguments(
    message: Dict[str, Any], *, strict: bool = True
) -> None:
    """Normalize assistant history tool call arguments in-place."""
    if message.get("role") != "assistant" or not isinstance(
        message.get("tool_calls"), list
    ):
        return

    for item in message["tool_calls"]:
        function = item.get("function") if isinstance(item, dict) else None
        if not isinstance(function, dict):

View on GitHub (pinned to 0132848349)

Solutions

  1. Use an object: '{"query": "..."}'
  2. For no-argument tools send '{}' (empty object)

Example fix

// before
"arguments": "[\"SF\"]"
// after
"arguments": "{\"city\": \"SF\"}"
Defensive patterns

Strategy: type-guard

Validate before calling

parsed = json.loads(args)
assert isinstance(parsed, dict), 'tool arguments must be a JSON object'

Type guard

def args_is_object(s):
    try: return isinstance(json.loads(s), dict)
    except Exception: return False

Try / catch

except ValueError as e: if 'JSON object' in str(e): wrap args as {"value": parsed} if appropriate

Prevention

When it happens

Trigger: Assistant tool_calls with arguments "[1,2]" or "\"text\"" — valid JSON but not an object.

Common situations: Wrapping arguments in an array because a model emitted them that way; sending a bare string for zero-arg functions instead of "{}".

Related errors


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