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.

    Returns

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Catch the ValueError and retry the request (optionally appending a corrective user message like 'Your tool arguments were invalid JSON, resend valid JSON')
  2. Raise max_tokens so the tool call is not truncated mid-JSON
  3. Switch to a model with reliable native function calling / strict tool-call JSON output
  4. 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

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

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/5c31dbd91445ba22. Report an issue: GitHub.