{"record":{"id":"814dd8672a4a3a30","repo":"sgl-project/sglang","slug":"kimi-k3-tool-parameters-properties-must-be-an-ob","errorCode":null,"errorMessage":"Kimi K3 tool parameters 'properties' must be an object","messagePattern":"Kimi K3 tool parameters 'properties' must be an object","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/function_call/kimik3_structural_tag.py","lineNumber":382,"sourceCode":"        )\n        for json_type, value_format in _argument_value_variants(\n            schema, root_schema, loose_strings=loose_strings\n        )\n    ]\n    if not variants:\n        raise ValueError(\"Kimi K3 additional parameter schema accepts no values\")\n    content = variants[0] if len(variants) == 1 else OrFormat(elements=variants)\n    return TagFormat(\n        begin='<|open|>argument key=\"',\n        content=content,\n        end=ARGUMENT_CLOSE,\n    )\n\n\ndef _strict_arguments_format(parameters: Dict[str, Any]) -> Format:\n    properties = parameters.get(\"properties\", {})\n    if not isinstance(properties, dict):\n        raise ValueError(\"Kimi K3 tool parameters 'properties' must be an object\")\n    required = parameters.get(\"required\", [])\n    if not isinstance(required, list) or not all(\n        isinstance(item, str) for item in required\n    ):\n        raise ValueError(\"Kimi K3 tool parameters 'required' must be a string list\")\n\n    required_set = set(required)\n    missing = required_set.difference(properties)\n    if missing:\n        raise ValueError(\n            f\"Kimi K3 required parameters are missing schemas: {sorted(missing)!r}\"\n        )\n\n    elements: List[Format] = []\n    for key, schema in properties.items():\n        if not isinstance(key, str) or not isinstance(schema, (bool, dict)):\n            raise ValueError(\"Kimi K3 tool property schemas must be JSON schemas\")\n        argument = _known_argument_format(key, schema, parameters)","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/function_call/kimik3_structural_tag.py#L364-L400","documentation":"The Kimi K3 strict arguments builder requires tool.parameters.properties to be a JSON object (dict) so it can emit a per-property argument format. A non-dict value (string, list, null-like) makes it impossible to enumerate properties, so it raises.","triggerScenarios":"A tool whose parameters dict has \"properties\": [...] or \"properties\": \"foo\" instead of an object mapping names to schemas.","commonSituations":"Schemas authored by hand or converted from OpenAPI/other formats that mangle properties into a list of {name, type} entries; LLM-generated tool definitions.","solutions":["Fix the tool definition so properties is an object: {\"name\": {schema}, ...}","Validate tool schemas with a JSON Schema draft validator against a proper JSON-Schema meta-schema before sending them","If converting from another format, map list-style params into an object"],"exampleFix":"// before\n\"parameters\": {\"type\": \"object\", \"properties\": [{\"name\": \"city\", \"type\": \"string\"}]}\n// after\n\"parameters\": {\"type\": \"object\", \"properties\": {\"city\": {\"type\": \"string\"}}}","handlingStrategy":"validation","validationCode":"assert isinstance(tool[\"parameters\"].get(\"properties\", {}), dict), \"properties must be an object\"","typeGuard":"def valid_properties(params: dict) -> bool:\n    p = params.get(\"properties\", {})\n    return isinstance(p, dict)","tryCatchPattern":"try:\n    resp = client.chat(..., tools=tools)\nexcept ValueError as e:\n    if \"properties\" in str(e):\n        fix_properties_shape(tools); retry_once = True\n    else:\n        raise","preventionTips":["Use standard JSON Schema authoring","Lint tools with jsonschema against the meta-schema","Never emit properties as a list"],"tags":["kimi-k3","json-schema","tool-calling","validation","properties"],"backgroundTag":"json-schema-validation-failed","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}