{"record":{"id":"f80fe575facd6fac","repo":"sgl-project/sglang","slug":"assistant-tool-call-function-arguments-must-be-val","errorCode":null,"errorMessage":"Assistant tool call function.arguments must be valid JSON.","messagePattern":"Assistant tool call function\\.arguments must be valid JSON\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/entrypoints/openai/serving_chat.py","lineNumber":132,"sourceCode":"    if role != \"tool\" or not isinstance(content, list):\n        return content\n    parts = content\n    is_openai_text_parts = all(\n        (isinstance(p, dict) and p.get(\"type\") == \"text\") or isinstance(p, str)\n        for p in parts\n    )\n    if is_openai_text_parts:\n        text_parts = [p.get(\"text\", \"\") if isinstance(p, dict) else p for p in parts]\n        return \" \".join(text_parts)\n    return content\n\n\ndef parse_tool_call_arguments(arguments: str) -> Dict[str, Any]:\n    \"\"\"Parse OpenAI tool call arguments for chat templates.\"\"\"\n    try:\n        parsed_arguments = orjson.loads(arguments)\n    except orjson.JSONDecodeError as exc:\n        raise ValueError(\n            \"Assistant tool call function.arguments must be valid JSON.\"\n        ) from exc\n\n    if not isinstance(parsed_arguments, dict):\n        raise ValueError(\n            \"Assistant tool call function.arguments must be a JSON object.\"\n        )\n\n    return parsed_arguments\n\n\ndef normalize_assistant_tool_call_arguments(\n    message: Dict[str, Any], *, strict: bool = True\n) -> None:\n    \"\"\"Normalize assistant history tool call arguments in-place.\"\"\"\n    if message.get(\"role\") != \"assistant\" or not isinstance(\n        message.get(\"tool_calls\"), list\n    ):","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/entrypoints/openai/serving_chat.py#L114-L150","documentation":"parse_tool_call_arguments fails when an assistant message's tool_call function.arguments string is not valid JSON. Prior assistant turns are re-rendered through chat templates, so their arguments must parse as JSON (SGLang uses orjson).","triggerScenarios":"POST /v1/chat/completions with messages containing {\"role\":\"assistant\",\"tool_calls\":[{\"function\":{\"arguments\":\"not json\"}}]}.","commonSituations":"Feeding back partial/streamed tool-call deltas whose arguments were concatenated incorrectly; models producing malformed arguments that are echoed back; hand-crafted conversation histories with placeholder arguments like '{...}'.","solutions":["Ensure arguments is a serialized JSON object string, e.g. '{\"city\": \"SF\"}'","If replaying streamed tool calls, accumulate argument fragments until finish_reason before sending back","Repair malformed history with orjson.loads + json.dumps round-trip"],"exampleFix":"// before\n{\"role\":\"assistant\",\"tool_calls\":[{\"id\":\"1\",\"type\":\"function\",\"function\":{\"name\":\"f\",\"arguments\":\"{city: SF}\"}}]}\n// after\n{\"role\":\"assistant\",\"tool_calls\":[{\"id\":\"1\",\"type\":\"function\",\"function\":{\"name\":\"f\",\"arguments\":\"{\\\"city\\\": \\\"SF\\\"}\"}}]}","handlingStrategy":"validation","validationCode":"import json\nfor tc in assistant_msg.get(\"tool_calls\", []):\n    json.loads(tc[\"function\"][\"arguments\"])  # must not raise","typeGuard":"def valid_tool_call_args(s):\n    try:\n        return isinstance(json.loads(s), dict)\n    except (json.JSONDecodeError, TypeError):\n        return False","tryCatchPattern":"except ValueError as e: if 'valid JSON' in str(e): repair args via json.dumps(parsed_obj) and resend","preventionTips":["Accumulate streamed argument fragments until finish_reason before echoing back","Round-trip histories through json.loads/dumps before resending"],"tags":["tool-calling","json","chat-template","openai-api","sglang"],"backgroundTag":"invalid-json-in-request","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}