BerriAI/litellm · error · ValueError
Failed to parse tool call arguments. Error: {original_error}
Error message
Failed to parse tool call arguments. Error: {original_error}. Arguments: {arguments} What it means
LiteLLM raises this ValueError after it receives a model's tool call and tries to parse the `arguments` string as JSON; even its internal repair pass failed. The message includes the original JSON parse error, the offending tool name/context, and the raw arguments. It almost always means the LLM emitted malformed JSON (truncated, concatenated, or quote-mangled) rather than a problem with your request.
Source
Thrown at litellm/litellm_core_utils/prompt_templates/common_utils.py:1801
"Repaired truncated tool call arguments for tool '%s' (%s). Original (%d chars): %.200s%s",
tool_name or "<unknown>",
context or "unknown context",
len(arguments),
arguments,
"..." if len(arguments) > 200 else "",
)
return repaired
error_parts: Final = ["Failed to parse tool call arguments"]
if tool_name:
error_parts.append(f"for tool '{tool_name}'")
if context:
error_parts.append(f"({context})")
error_message: Final = " ".join(error_parts) + f". Error: {original_error}. Arguments: {arguments}"
raise ValueError(error_message) from original_error
def split_concatenated_json_objects(raw: str) -> list[dict[str, Any]]:
"""
Split a string that contains one or more concatenated JSON objects into
a list of parsed dicts.
LLM providers (notably Bedrock Claude Sonnet 4.5) sometimes return
multiple tool-call argument objects concatenated in a single
``arguments`` string, e.g.::
'{"command":["curl",...]}{"command":["curl",...]}{"command":["curl",...]}'
``json.loads()`` fails on this with ``JSONDecodeError: Extra data``.
This helper uses ``json.JSONDecoder.raw_decode()`` to walk the string
and extract each JSON object individually.
ReturnsView on GitHub (pinned to 6c2dcb801b)
Solutions
- Catch the ValueError and retry the request (optionally appending a corrective user message like 'Your tool arguments were invalid JSON, resend valid JSON')
- Raise max_tokens so the tool call is not truncated mid-JSON
- Switch to a model with reliable native function calling / strict tool-call JSON output
- Pre-sanitize arguments yourself with a JSON repair pass (e.g. json_repair) before invoking the tool, if you are processing raw model output
Example fix
# before
resp = litellm.completion(model="bedrock/anthropic.claude-3-5-sonnet", messages=msgs, tools=tools)
args = json.loads(resp.choices[0].message.tool_calls[0].function.arguments) # ValueError here
# after
import json, litellm
for attempt in range(3):
try:
resp = litellm.completion(model="gpt-4o", messages=msgs, tools=tools)
tc = resp.choices[0].message.tool_calls[0]
args = json.loads(tc.function.arguments)
break
except ValueError:
msgs.append({"role": "assistant", "content": resp.choices[0].message.content or ""})
msgs.append({"role": "user", "content": "Your last tool arguments were invalid JSON. Resend the tool call with valid JSON."}) Defensive patterns
Strategy: retry
Try / catch
try:
resp = litellm.completion(model=model, messages=messages, tools=tools)
args = json.loads(resp.choices[0].message.tool_calls[0].function.arguments)
except ValueError as e:
if "Failed to parse tool call arguments" in str(e):
messages = messages + [
{"role": "assistant", "content": resp.choices[0].message.content or ""},
{"role": "user", "content": "Your tool arguments were invalid JSON. Resend the tool call with valid JSON only."},
]
resp = litellm.completion(model=model, messages=messages, tools=tools)
else:
raise Prevention
- Use models with native, reliable function calling
- Set max_tokens high enough that tool-call JSON is never truncated
- Keep temperature low when tool arguments are expected
- Log raw tool_call arguments so malformed output is diagnosable
When it happens
Trigger: Calling completion()/acompletion() with tools= against a model that returns a tool_call whose arguments are invalid JSON (e.g. single quotes, unescaped newlines, truncated output due to max_tokens, or multiple concatenated JSON objects that repair cannot split). Also triggered when a weaker model hallucinates non-JSON arguments.
Common situations: Small/open-source models (or high-temperature runs) producing unparseable tool arguments; max_tokens set so low the JSON is cut off; Bedrock Claude Sonnet 4.5 returning concatenated JSON objects in one arguments string; providers whose strict JSON mode is not enabled.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Error parsing chunk: {e}, Received chunk: {chunk}
- Failed to parse DashScope response as JSON: {e}
- Chunk cannot be parsed as JSON: {e}
- Mavvrik FOCUS destination: response missing 'url' field: {re
- Failed to parse prompt response for '{prompt_id}': {e}
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/5c31dbd91445ba22.
Report an issue: GitHub.