xtekky/gpt4free · error · ValueError

Tool function arguments must be a dictionary or a json strin

Error message

Tool function arguments must be a dictionary or a json string

What it means

ToolHandler.validate_arguments in g4f/tools/run_tools.py raises this ValueError when a tool call's 'arguments' field, after being parsed, is not a JSON object (dict). The method accepts either a dict directly or a JSON string (which it json.loads first), but any other JSON type (array, number, boolean, null) fails validation. Note that a malformed JSON string fails earlier, inside json.loads, with a JSONDecodeError.

Source

Thrown at g4f/tools/run_tools.py:166

    Providers that extend ``OpenaiTemplate`` (or set ``supports_native_tools = True``)
    are assumed to forward ``tools``/``tool_choice`` to an OpenAI-compatible endpoint
    and therefore do not need prompt-injection emulation.
    """
    return bool(getattr(provider, "supports_native_tools", False))


class ToolHandler:
    """Handles processing of different tool types"""

    @staticmethod
    def validate_arguments(data: dict) -> dict:
        """Validate and parse tool arguments"""
        if "arguments" in data:
            if isinstance(data["arguments"], str):
                data["arguments"] = json.loads(data["arguments"])
            if not isinstance(data["arguments"], dict):
                raise ValueError(
                    "Tool function arguments must be a dictionary or a json string"
                )
            else:
                return filter_none(**data["arguments"])
        else:
            return {}

    @staticmethod
    async def process_search_tool(messages: Messages, tool: dict) -> Messages:
        """Process search tool requests"""
        messages = messages.copy()
        args = ToolHandler.validate_arguments(tool["function"])
        messages[-1]["content"], sources = await do_search(
            messages[-1]["content"], **args
        )
        return messages, sources

    @staticmethod

View on GitHub (pinned to 973504e177)

Solutions

  1. Fix the payload so arguments is a JSON object string, e.g. '{"query": "..."}' — not an array or scalar.
  2. If the model produced the bad arguments, switch to a model/provider with reliable function-calling, or add a repair prompt asking the model to re-emit arguments as a JSON object.
  3. Pre-validate before calling the handler: parse the string yourself and confirm isinstance(parsed, dict), returning a user-facing error instead of a crash.
  4. Catch ValueError (and json.JSONDecodeError) around the tool-processing call to skip/log the malformed tool call.

Example fix

// before
arguments = "['latest news']"  // array string -> ValueError

// after
arguments = "{\"query\": \"latest news\"}"  // JSON object string
Defensive patterns

Strategy: validation

Validate before calling

import json

def is_valid_tool_arguments(fn: dict) -> bool:
    args = fn.get("arguments")
    if isinstance(args, str):
        try:
            args = json.loads(args)
        except json.JSONDecodeError:
            return False
    return isinstance(args, dict)

Type guard

def is_tool_args_dict(value) -> bool:
    if isinstance(value, str):
        try:
            value = json.loads(value)
        except json.JSONDecodeError:
            return False
    return isinstance(value, dict)

Try / catch

try:
    result = await ToolHandler.process_search_tool(messages, tool)
except ValueError as e:
    if "arguments" in str(e):
        # log and skip the malformed tool call, ask the model to re-emit
        ...
    raise

Prevention

When it happens

Trigger: Calling a tool-processing API (e.g. ToolHandler.process_search_tool or any handler that calls validate_arguments(tool['function'])) where tool['function']['arguments'] is a JSON string like '[1,2]', '"text"', '5', 'null', or an already-parsed Python list/None. Typically happens when an LLM provider emits malformed tool-call arguments (a common failure of smaller models).

Common situations: Switching to a provider whose models emit non-object tool arguments; aggressive logit or cheap models returning arrays instead of objects; hand-built tool payloads in tests; middleware that pre-parses arguments into non-dict types.

Related errors


AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14). Data as JSON: /api/errors/79dda504a0ceeaee. Report an issue: GitHub.