sgl-project/sglang · error · ValueError

Kimi K3 tool parameters 'additionalProperties' must be a sch

Error message

Kimi K3 tool parameters 'additionalProperties' must be a schema

What it means

tool.parameters.additionalProperties must be a JSON schema value: True (any value), a dict (schema for extra keys), or False (no extras). Any other value (string, list, number, null) is neither a valid schema nor the explicit 'closed' marker, so the strict builder rejects it.

Source

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

        if argument is None:
            if key in required_set:
                raise ValueError(
                    f"Kimi K3 required parameter {key!r} accepts no values"
                )
            continue
        elements.append(
            argument if key in required_set else OptionalFormat(content=argument)
        )

    additional = parameters.get("additionalProperties", True)
    if additional is True:
        elements.append(StarFormat(content=_dynamic_argument_format(True, parameters)))
    elif isinstance(additional, dict):
        elements.append(
            StarFormat(content=_dynamic_argument_format(additional, parameters))
        )
    elif additional is not False:
        raise ValueError(
            "Kimi K3 tool parameters 'additionalProperties' must be a schema"
        )
    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="")

View on GitHub (pinned to 0132848349)

Solutions

  1. Use boolean True/False or an object schema for additionalProperties
  2. Fix upstream serialization so booleans stay booleans (yaml quotes, env vars)
  3. Validate the schema with a JSON Schema meta-schema check before submission

Example fix

// before
"additionalProperties": "false"
// after
"additionalProperties": False
Defensive patterns

Strategy: validation

Validate before calling

add = params.get("additionalProperties", None)
assert add is None or isinstance(add, (bool, dict)), "additionalProperties must be bool or schema"

Type guard

def valid_additional_properties(params: dict) -> bool:
    a = params.get("additionalProperties", None)
    return a is None or isinstance(a, (bool, dict))

Try / catch

try:
    build_tag(tools)
except ValueError as e:
    if "additionalProperties" in str(e):
        coerce_bool_schema_fields(tools)
    else:
        raise

Prevention

When it happens

Trigger: "additionalProperties": "false" (string) or "additionalProperties": ["extra"] in a tool schema sent with a Kimi K3 tool-call request.

Common situations: Schemas serialized from YAML/config where booleans become strings; hand-written configs confusing additionalProperties with a list of allowed extra keys; LLM-generated schemas.

Related errors


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