sgl-project/sglang · error · ValueError

Kimi K3 strict tool {tool.function.name!r} must define param

Error message

Kimi K3 strict tool {tool.function.name!r} must define parameters

What it means

_tool_arguments_format requires each strict tool's parameters field to be a dict (JSON object schema). Tools with parameters None are tolerated (no arguments), but a non-dict value such as a string or list cannot be interpreted as an object schema and fails.

Source

Thrown at python/sglang/srt/function_call/kimik3_structural_tag.py:439

        )
    if not elements:
        return ConstStringFormat(value="")
    return SequenceFormat(elements=elements)


def _tool_arguments_format(tool: Tool) -> Format:
    parameters = tool.function.parameters
    if not tool.function.strict:
        root_schema = parameters if isinstance(parameters, dict) else {}
        return StarFormat(
            content=_dynamic_argument_format(True, root_schema, loose_strings=True)
        )
    if parameters is None:
        # Server-side strict levels mark tools without parameters strict too;
        # they take no arguments rather than failing the whole constraint.
        return ConstStringFormat(value="")
    if not isinstance(parameters, dict):
        raise ValueError(
            f"Kimi K3 strict tool {tool.function.name!r} must define parameters"
        )
    schema_types = _schema_types(parameters, parameters)
    if "object" not in schema_types:
        raise ValueError(
            f"Kimi K3 tool {tool.function.name!r} parameters must be an object schema"
        )
    return _strict_arguments_format(parameters)


def _tool_call_tag(tool: Tool, arguments_format: Optional[Format] = None) -> TagFormat:
    name = _escape_attr(tool.function.name)
    if arguments_format is None:
        arguments_format = _tool_arguments_format(tool)
    return TagFormat(
        begin=f'{CALL_OPEN} tool="{name}" index="',
        content=SequenceFormat(
            elements=[

View on GitHub (pinned to 0132848349)

Solutions

  1. Parse parameters into a dict before sending (json.loads if it is a JSON string)
  2. Ensure parameters is either omitted/null (no args) or an object schema like {"type": "object", "properties": {...}}
  3. Add a client-side type check on Tool objects before the request

Example fix

// before
{"name": "f", "parameters": "{\"type\": \"object\"}"}
// after
{"name": "f", "parameters": {"type": "object", "properties": {}}}
Defensive patterns

Strategy: validation

Validate before calling

params = tool["function"].get("parameters")
assert params is None or isinstance(params, dict), "parameters must be an object schema or omitted"

Type guard

def valid_tool_parameters(tool: dict) -> bool:
    p = tool.get("function", tool).get("parameters", None)
    return p is None or isinstance(p, dict)

Try / catch

try:
    resp = client.chat(..., tools=tools)
except ValueError as e:
    if "must define parameters" in str(e):
        tools = parse_parameters_json(tools)  # then retry
    else:
        raise

Prevention

When it happens

Trigger: A tool whose function.parameters is a JSON-encoded string or a list rather than a parsed object, e.g. "parameters": "{'type': 'object'}" passed unparsed.

Common situations: Passing serialized JSON strings for parameters instead of dicts; converting from OpenAPI specs where the schema stayed a string; LLM-authored tool specs.

Related errors


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