{"record":{"id":"4ab7164778b90723","repo":"sgl-project/sglang","slug":"assistant-tool-call-function-arguments-must-be-a-j-4ab716","errorCode":null,"errorMessage":"Assistant tool call function.arguments must be a JSON object.","messagePattern":"Assistant tool call function\\.arguments must be a JSON object\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/entrypoints/openai/encoding_dsv4.py","lineNumber":175,"sourceCode":"def encode_arguments_to_dsml(tool_call: Dict[str, str]) -> str:\n    \"\"\"\n    Encode tool call arguments into DSML parameter format.\n\n    Args:\n        tool_call: Dict with \"name\" and \"arguments\" keys.\n\n    Returns:\n        DSML-formatted parameter string.\n    \"\"\"\n    p_dsml_template = '<{dsml_token}parameter name=\"{key}\" string=\"{is_str}\">{value}</{dsml_token}parameter>'\n    P_dsml_strs = []\n\n    raw_arguments = tool_call[\"arguments\"]\n    arguments = (\n        json.loads(raw_arguments) if isinstance(raw_arguments, str) else raw_arguments\n    )\n    if not isinstance(arguments, dict):\n        raise ValueError(\n            \"Assistant tool call function.arguments must be a JSON object.\"\n        )\n\n    for k, v in arguments.items():\n        p_dsml_str = p_dsml_template.format(\n            dsml_token=dsml_token,\n            key=k,\n            is_str=\"true\" if isinstance(v, str) else \"false\",\n            value=v if isinstance(v, str) else to_json(v),\n        )\n        P_dsml_strs.append(p_dsml_str)\n\n    return \"\\n\".join(P_dsml_strs)\n\n\ndef decode_dsml_to_arguments(\n    tool_name: str, tool_args: Dict[str, Tuple[str, str]]\n) -> Dict[str, str]:","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/entrypoints/openai/encoding_dsv4.py#L157-L193","documentation":"encode_arguments_to_dsml requires tool_call['arguments'] to decode to a JSON object (dict). If the string parses to a list/number, or the value itself is not a dict, ValueError is raised.","triggerScenarios":"Assistant tool_call with function.arguments = '[1,2]' (JSON array string), '\"42\"', or a raw non-dict value like a list passed directly.","commonSituations":"Agents recording tool calls whose arguments were arrays; clients storing pre-serialized non-object JSON; upstream model emitting malformed arguments.","solutions":["Make arguments a JSON object string, e.g. '{\"query\": \"...\"}'.","If arguments are legitimately an array, wrap them: '{\"items\": [...]}'.","Validate tool_call arguments with json.loads + isinstance dict before sending history back."],"exampleFix":"# before\n{\"name\":\"search\",\"arguments\":\"[\\\"a\\\",\\\"b\\\"]\"}\n# after\n{\"name\":\"search\",\"arguments\":\"{\\\"terms\\\":[\\\"a\\\",\\\"b\\\"]}\"}","handlingStrategy":"type-guard","validationCode":"import json\nargs=json.loads(tc['function']['arguments']) if isinstance(tc['function']['arguments'],str) else tc['function']['arguments']\nassert isinstance(args,dict)","typeGuard":"def args_is_dict(tc):\n    a=tc['function']['arguments']\n    a=json.loads(a) if isinstance(a,str) else a\n    return isinstance(a,dict)","tryCatchPattern":null,"preventionTips":["Always serialize tool arguments as JSON objects.","Wrap non-object payloads in a named key."],"tags":["deepseek","tool-calls","json-validation"],"backgroundTag":"tool-arguments-not-json-object","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}