From 9305164bf394c10b2b62e8d4e6ad2ba475323907 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Sat, 21 Mar 2026 07:20:41 -0700 Subject: [PATCH] fix: add None-entry guard to tool_calls loops in run_agent, batch_runner, and mini_swe_runner (#2316) Co-authored-by: Dilee --- batch_runner.py | 1 + mini_swe_runner.py | 1 + run_agent.py | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/batch_runner.py b/batch_runner.py index 865c10f3..ed00665e 100644 --- a/batch_runner.py +++ b/batch_runner.py @@ -128,6 +128,7 @@ def _extract_tool_stats(messages: List[Dict[str, Any]]) -> Dict[str, Dict[str, i # Track tool calls from assistant messages if msg["role"] == "assistant" and "tool_calls" in msg and msg["tool_calls"]: for tool_call in msg["tool_calls"]: + if not tool_call or not isinstance(tool_call, dict): continue tool_name = tool_call["function"]["name"] tool_call_id = tool_call["id"] diff --git a/mini_swe_runner.py b/mini_swe_runner.py index f5e8b59f..e0df6695 100644 --- a/mini_swe_runner.py +++ b/mini_swe_runner.py @@ -339,6 +339,7 @@ class MiniSWERunner: # Add tool calls in XML format for tool_call in msg["tool_calls"]: + if not tool_call or not isinstance(tool_call, dict): continue try: arguments = json.loads(tool_call["function"]["arguments"]) \ if isinstance(tool_call["function"]["arguments"], str) \ diff --git a/run_agent.py b/run_agent.py index faa33de1..ae555e41 100644 --- a/run_agent.py +++ b/run_agent.py @@ -1618,6 +1618,7 @@ class AIAgent: # Add tool calls wrapped in XML tags for tool_call in msg["tool_calls"]: + if not tool_call or not isinstance(tool_call, dict): continue # Parse arguments - should always succeed since we validate during conversation # but keep try-except as safety net try: @@ -6783,6 +6784,7 @@ class AIAgent: if msg.get("role") == "assistant" and msg.get("tool_calls"): tool_names = [] for tc in msg["tool_calls"]: + if not tc or not isinstance(tc, dict): continue fn = tc.get("function", {}) tool_names.append(fn.get("name", "unknown")) msg["content"] = f"Calling the {', '.join(tool_names)} tool{'s' if len(tool_names) > 1 else ''}..." @@ -6825,6 +6827,7 @@ class AIAgent: if msg.get("role") == "assistant" and msg.get("tool_calls"): tool_names = [] for tc in msg["tool_calls"]: + if not tc or not isinstance(tc, dict): continue fn = tc.get("function", {}) tool_names.append(fn.get("name", "unknown")) msg["content"] = f"Calling the {', '.join(tool_names)} tool{'s' if len(tool_names) > 1 else ''}..." @@ -6944,6 +6947,7 @@ class AIAgent: if isinstance(m, dict) and m.get("role") == "tool" } for tc in msg["tool_calls"]: + if not tc or not isinstance(tc, dict): continue if tc["id"] not in answered_ids: err_msg = { "role": "tool",