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
@staticmethodView on GitHub (pinned to 973504e177)
Solutions
- Fix the payload so arguments is a JSON object string, e.g. '{"query": "..."}' — not an array or scalar.
- 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.
- Pre-validate before calling the handler: parse the string yourself and confirm isinstance(parsed, dict), returning a user-facing error instead of a crash.
- 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
- Always serialize tool-call arguments as a JSON object string, never an array or scalar
- Prefer providers/models with reliable native function calling
- Validate arguments shape before handing tool dicts to g4f handlers
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
- Provider '{item}' not found
- Label must be provided
- Provider with label '{label}' not found
- Prompt is empty.
- Prompt is empty.
AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14).
Data as JSON: /api/errors/79dda504a0ceeaee.
Report an issue: GitHub.