From 64164af7aa37744b769fce2dbd82a42853d484d5 Mon Sep 17 00:00:00 2001 From: Sameer Kankute Date: Thu, 9 Apr 2026 10:05:32 +0530 Subject: [PATCH] =?UTF-8?q?fix(bedrock):=20use=20iterative=20walk=20for=20?= =?UTF-8?q?custom=E2=86=92object=20schema=20normalization?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoids nested recursive _fix_schema flagged by recursive_detector CI. Made-with: Cursor --- litellm/llms/bedrock/common_utils.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/litellm/llms/bedrock/common_utils.py b/litellm/llms/bedrock/common_utils.py index f99f0102d83..a8d2fb9ad72 100644 --- a/litellm/llms/bedrock/common_utils.py +++ b/litellm/llms/bedrock/common_utils.py @@ -72,34 +72,42 @@ def remove_custom_field_from_tools(request_body: dict) -> None: def normalize_json_schema_custom_types_to_object(schema: dict) -> None: """ - In-place: replace JSON Schema ``type: \"custom\"`` with ``\"object\"`` recursively. + In-place: replace JSON Schema ``type: \"custom\"`` with ``\"object`` (iterative walk). Anthropic / Claude Code use ``custom`` for tool schemas; Bedrock Invoke and Bedrock Converse only accept standard JSON Schema type strings. - """ - def _fix_schema(node: Any) -> None: + Uses an explicit stack (not recursion) to satisfy recursive-function guards in CI. + """ + stack: List[Any] = [schema] + seen: set[int] = set() + while stack: + node = stack.pop() if not isinstance(node, dict): - return + continue + node_id = id(node) + if node_id in seen: + continue + seen.add(node_id) if node.get("type") == "custom": node["type"] = "object" items = node.get("items") if isinstance(items, dict): - _fix_schema(items) + stack.append(items) addl = node.get("additionalProperties") if isinstance(addl, dict): - _fix_schema(addl) + stack.append(addl) props = node.get("properties") if isinstance(props, dict): for sub in props.values(): - _fix_schema(sub) + if isinstance(sub, dict): + stack.append(sub) for combiner in ("allOf", "anyOf", "oneOf"): arr = node.get(combiner) if isinstance(arr, list): for sub in arr: - _fix_schema(sub) - - _fix_schema(schema) + if isinstance(sub, dict): + stack.append(sub) def normalize_tool_input_schema_types_for_bedrock_invoke(request_body: dict) -> None: