langchain-ai/langchain · error · ValueError
Tool arguments must be specified as a dict, received: {res['
Error message
Tool arguments must be specified as a dict, received: {res['args']} What it means
Raised by PydanticToolsParser.parse_result (non-partial mode) when a parsed tool result's 'args' is not a dict — e.g. the model returned a JSON list, string, or number as the tool arguments. Constructing tool(**res['args']) requires keyword arguments, so a non-mapping args payload is a hard ValueError.
Source
Thrown at libs/core/langchain_core/output_parsers/openai_tools.py:356
name_dict_v2: dict[str, TypeBaseModel] = {
tool.model_config.get("title") or tool.__name__: tool
for tool in self.tools
if issubclass(tool, BaseModel)
}
name_dict_v1: dict[str, TypeBaseModel] = {
tool.__name__: tool for tool in self.tools if issubclass(tool, BaseModelV1)
}
name_dict: dict[str, TypeBaseModel] = {**name_dict_v2, **name_dict_v1}
pydantic_objects = []
for res in json_results:
if not isinstance(res["args"], dict):
if partial:
continue
msg = (
f"Tool arguments must be specified as a dict, received: "
f"{res['args']}"
)
raise ValueError(msg)
try:
tool = name_dict[res["type"]]
except KeyError as e:
available = ", ".join(name_dict.keys()) or "<no_tools>"
msg = (
f"Unknown tool type: {res['type']!r}. Available tools: {available}"
)
raise OutputParserException(msg) from e
try:
pydantic_objects.append(tool(**res["args"]))
except (ValidationError, ValueError):
if partial:
continue
has_max_tokens_stop_reason = any(
generation.message.response_metadata.get("stop_reason")
== "max_tokens"View on GitHub (pinned to e32fa9a52e)
Solutions
- Define the tool schema so top-level parameters are a JSON object (properties/type: object), not an array
- Improve the prompt/schema so the model always emits an object for arguments
- Catch ValueError and retry the call, or pre-validate res['args'] and skip/repair non-dict entries
Example fix
# before
class SearchArgs(BaseModel):
query: str
# model emitted args as a bare string "cat videos"
# after
# enforce object arguments in the tool description/system prompt:
system = "Tool arguments MUST be a JSON object, e.g. {\"query\": \"...\"}" Defensive patterns
Strategy: validation
Validate before calling
for res in json_results:
if not isinstance(res["args"], dict):
continue # or repair: {"value": res["args"]}
# only then call the parser Type guard
def has_dict_args(res: dict) -> bool:
return isinstance(res.get("args"), dict) Try / catch
try:
objs = parser.parse_result(result)
except ValueError as e:
if "must be specified as a dict" in str(e):
objs = [o for o in parser.parse_result(result, partial=True) if o is not None] # skip bad entries Prevention
- Design tool schemas with top-level object parameters
- Show argument examples in the tool description
When it happens
Trigger: Model emits tool arguments as a JSON array or scalar (e.g. "[1,2]" or "\"text\"") instead of an object; partial=False so the parser cannot silently skip the bad entry.
Common situations: Tool schemas whose parameters are an array at top level (invalid per OpenAI spec but sometimes written); models trained to emit positional arguments; degenerate outputs from small local models.
Related errors
- Either data or path must be provided
- Arguments 'observation' & 'llm_output' are required if 'send
- ToolMessage content should be a string or a list of string/d
- If multiple pydantic schemas are provided then args_only sho
- Dict Pydantic schema unsupported with args_only: {self.pydan
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/11d0d697396732a3.
Report an issue: GitHub.