sgl-project/sglang · error · TypeError

tool call function name must be a string

Error message

tool call function name must be a string

What it means

Raised by _tool_call_name_and_args when rendering Inkling-formatted messages: the tool_call object's function.name field is missing or not a string. The renderer expects OpenAI-style tool call dicts ({'function': {'name': str, 'arguments': ...}}) and refuses anything else before serializing to Inkling tool-call JSON.

Source

Thrown at python/sglang/srt/parser/inkling_renderer.py:318

        tool = _as_mapping(tool_value)
        function = _as_mapping(tool.get("function", {}))
        tool_specs.append(
            {
                "description": function.get("description") or "",
                "name": function["name"],
                "parameters": function.get("parameters") or {},
                "type": tool.get("type", "function"),
            }
        )
    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

  1. Inspect the failing message's tool_calls[i]['function']['name'] and ensure it is a non-None string
  2. If the name comes from regex parsing of model output, tighten the pattern so unmatched names are dropped instead of passed through
  3. Validate tool call dicts against the OpenAI schema before rendering

Example fix

// before
msg = {"role": "assistant", "tool_calls": [{"function": {"arguments": "{\"x\": 1}"}}]}
render_inkling_messages([msg])
// after
msg = {"role": "assistant", "tool_calls": [{"function": {"name": "get_weather", "arguments": "{\"x\": 1}"}}]}
render_inkling_messages([msg])
Defensive patterns

Strategy: validation

Validate before calling

def valid_tool_call(tc):
    fn = tc.get("function") or {}
    return isinstance(fn.get("name"), str) and bool(fn.get("name"))

msgs = [m for m in messages if not m.get("tool_calls") or all(valid_tool_call(tc) for tc in m["tool_calls"])]

Type guard

def is_valid_tool_call(tc: Any) -> TypeGuard[dict]:
    fn = tc.get("function") if isinstance(tc, dict) else None
    return isinstance(fn, dict) and isinstance(fn.get("name"), str)

Try / catch

try:
    render_inkling_messages(msgs)
except TypeError as e:
    if "function name" in str(e):
        drop_or_repair_bad_tool_calls(msgs)  # then retry
    else:
        raise

Prevention

When it happens

Trigger: Calling render_inkling_messages with a message whose 'tool_calls' entries have function.name set to None, a number, or absent entirely; e.g. {'tool_calls': [{'id': '1', 'type': 'function', 'function': {'arguments': '{}'}}]}.

Common situations: Hand-built assistant messages in test fixtures, LLM-generated tool calls parsed from raw text where the name capture group failed, or upstream model output missing the function name field.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/92a40ab6e3e2b4cb. Report an issue: GitHub.