{"record":{"id":"21d9d69e2aa8ad2c","repo":"sgl-project/sglang","slug":"kimi-k3-tool-property-schemas-must-be-json-schemas","errorCode":null,"errorMessage":"Kimi K3 tool property schemas must be JSON schemas","messagePattern":"Kimi K3 tool property schemas must be JSON schemas","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/function_call/kimik3_structural_tag.py","lineNumber":399,"sourceCode":"    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)\n        if argument is None:\n            if key in required_set:\n                raise ValueError(\n                    f\"Kimi K3 required parameter {key!r} accepts no values\"\n                )\n            continue\n        elements.append(\n            argument if key in required_set else OptionalFormat(content=argument)\n        )\n\n    additional = parameters.get(\"additionalProperties\", True)\n    if additional is True:\n        elements.append(StarFormat(content=_dynamic_argument_format(True, parameters)))\n    elif isinstance(additional, dict):\n        elements.append(\n            StarFormat(content=_dynamic_argument_format(additional, parameters))\n        )","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/function_call/kimik3_structural_tag.py#L381-L417","documentation":"Each entry in tool.parameters.properties must be a property name (str) mapped to a JSON schema (bool for true/false schemas, or an object). A key or value of any other type (e.g. a schema given as a string or list) cannot be converted into a tag format, so the strict builder raises.","triggerScenarios":"A properties entry like \"city\": \"string\" (bare type string) or a non-string key, when building the Kimi K3 structural tag.","commonSituations":"Shorthand schemas from tutorials (\"type\": \"string\" written as just \"string\"); tool definitions produced by LLMs that inline type names; serialization that turns schema dicts into strings.","solutions":["Wrap bare types into proper schema objects: {\"type\": \"string\"}","Ensure every key is a string and every value is a dict or boolean","Run the tool schema through a JSON Schema validator before passing it to the server"],"exampleFix":"// before\n\"properties\": {\"city\": \"string\"}\n// after\n\"properties\": {\"city\": {\"type\": \"string\"}}","handlingStrategy":"validation","validationCode":"for k, v in params.get(\"properties\", {}).items():\n    assert isinstance(k, str) and isinstance(v, (bool, dict)), f\"bad property {k}\"","typeGuard":"def valid_property_schemas(params: dict) -> bool:\n    return all(\n        isinstance(k, str) and isinstance(v, (bool, dict))\n        for k, v in params.get(\"properties\", {}).items()\n    )","tryCatchPattern":"try:\n    build_tag(tools)\nexcept ValueError as e:\n    if \"must be JSON schemas\" in str(e):\n        wrap_bare_types(tools)\n    else:\n        raise","preventionTips":["Never use shorthand bare type strings","Wrap every property value in {\"type\": ...}"],"tags":["kimi-k3","json-schema","tool-calling","validation"],"backgroundTag":"json-schema-validation-failed","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}