sgl-project/sglang · error · TypeError
tool call function arguments must decode to an object
Error message
tool call function arguments must decode to an object
What it means
Raised when a tool call's function.arguments field, after JSON decoding, is not a JSON object/Mapping. String arguments are json.loads-ed first; if the result is a list, number, string, or null, or if arguments was a non-string non-mapping value directly, this TypeError fires.
Source
Thrown at python/sglang/srt/parser/inkling_renderer.py:326
}
)
return _canonical_json(tool_specs)
def _tool_call_name_and_args(tool_call_value: Any) -> tuple[str, Mapping[str, Any]]:
tool_call = _as_mapping(tool_call_value)
function = _as_mapping(tool_call.get("function", {}))
name = function.get("name")
if not isinstance(name, str):
raise TypeError("tool call function name must be a string")
raw_args = function.get("arguments") or {}
if isinstance(raw_args, str):
args = json.loads(raw_args) if raw_args else {}
else:
args = raw_args
if not isinstance(args, Mapping):
raise TypeError("tool call function arguments must decode to an object")
return name, args
def _tool_call_json(name: str, args: Mapping[str, Any]) -> str:
name_json = json.dumps(name, ensure_ascii=False, allow_nan=False)
return f'{{"name":{name_json},"args":{_canonical_json(args)}}}'
View on GitHub (pinned to 0132848349)
Solutions
- Ensure arguments decodes to a JSON object (dict), e.g. '{"query": "..."}' not '["..."]' or '"text"'
- If your tool genuinely takes positional args, wrap them in an object like {"args": [...]}
- Log the raw arguments value to spot double-encoding or list-shaped payloads
Example fix
// before
call = {"function": {"name": "f", "arguments": "[1, 2]"}}
// after
call = {"function": {"name": "f", "arguments": "{\"args\": [1, 2]}"}} Defensive patterns
Strategy: validation
Validate before calling
import json
from collections.abc import Mapping
def args_are_object(fn):
raw = fn.get("arguments") or {}
args = json.loads(raw) if isinstance(raw, str) and raw else raw
return isinstance(args, Mapping) Type guard
def has_object_args(tc: Any) -> TypeGuard[dict]:
fn = tc.get("function") if isinstance(tc, dict) else None
if not isinstance(fn, dict):
return False
raw = fn.get("arguments") or {}
args = json.loads(raw) if isinstance(raw, str) and raw else raw
return isinstance(args, Mapping) Try / catch
try:
render_inkling_messages(msgs)
except TypeError as e:
if "arguments" in str(e):
normalize_tool_call_args(msgs) # wrap scalars/lists into {"args": value}
else:
raise Prevention
- Emit arguments as a JSON object string, never a list/scalar
- When parsing model output, wrap non-object argument payloads in {"args": ...}
- Unit-test argument decoding against your model's actual output shapes
When it happens
Trigger: tool_calls[i]['function']['arguments'] is a JSON string encoding a non-object like '"[1,2]"', '"5"', or arguments passed directly as a Python list [1,2] instead of a dict.
Common situations: Models emitting array-valued arguments, upstream parsers storing positional args as a list, or double-encoded JSON where decoding yields a scalar.
Related errors
- expected mapping, got {type(value).__name__}
- tool call function name must be a string
- MXFP8 fused prologue requires head_dim-aligned Q/K/V.
- MXFP8 fused prologue requires K/V scale buffers.
- MXFP8 fused prologue requires interleaved K/V scale buffers
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/95232cba0bd3dfd3.
Report an issue: GitHub.