diff --git a/litellm/litellm_core_utils/prompt_templates/common_utils.py b/litellm/litellm_core_utils/prompt_templates/common_utils.py index 6c45622649f..cdc8da07321 100644 --- a/litellm/litellm_core_utils/prompt_templates/common_utils.py +++ b/litellm/litellm_core_utils/prompt_templates/common_utils.py @@ -1,4 +1,4 @@ -""" +""" Common utility functions used for translating messages across providers """ @@ -2382,7 +2382,24 @@ def parse_tool_call_arguments( return {} try: - return json.loads(arguments) + parsed = json.loads(arguments) + if isinstance(parsed, str): + # Double-encoded JSON: json.dumps applied twice by the caller (common + # in agent frameworks that serialise tool arguments through a store). + # Anthropic's tool_use.input must be an object, not a string, so + # unwrap one extra layer and warn so callers can fix the root cause. + verbose_logger.warning( + "Tool call arguments for tool '%s' (%s) decoded to a string " + "instead of an object — double-encoded JSON detected. " + "Attempting second decode.", + tool_name or "", + context or "unknown context", + ) + try: + parsed = json.loads(parsed) + except json.JSONDecodeError: + pass + return parsed except json.JSONDecodeError as original_error: repaired: Final = _attempt_json_repair(arguments) if repaired is not None: