-
Notifications
You must be signed in to change notification settings - Fork 273
Description
Checks
- I have updated to the lastest minor and patch version of Strands
- I have checked the documentation and this is not expected behavior
- I have searched ./issues and there are no duplicates of my issue
Strands Version
1.29.0
Tools Package Version
0.2.22
Tools used
- batch
- current_time
Python Version
3.12.12
Operating System
Windows, Linux(ARM64)
Installation Method
pip
Steps to Reproduce
from strands import Agent
from strands_tools import batch, current_time
agent = Agent(tools=[batch, current_time])
result = agent("What is the current time in UTC, US/Pacific, US/Eastern, Europe/London, Asia/Tokyo, and Australia/Sydney?")The LLM generates this tool call:
batch (invocations: [
{'name': 'current_time', 'arguments': {'timezone': 'UTC'}},
{'name': 'current_time', 'arguments': {'timezone': 'US/Pacific'}},
{'name': 'current_time', 'arguments': {'timezone': 'US/Eastern'}},
{'name': 'current_time', 'arguments': {'timezone': 'Europe/London'}},
{'name': 'current_time', 'arguments': {'timezone': 'Asia/Tokyo'}},
{'name': 'current_time', 'arguments': {'timezone': 'Australia/Sydney'}}
])
Expected Behavior
The batch tool should execute all 6 current_time invocations and return their results:
Batch execution completed with 6 tool(s):
✓ current_time: Success
✓ current_time: Success
...
Actual Behavior
With unpatched code (Bug 1):
The batch tool returns 0 results — invocations is silently empty:
Batch execution completed with 0 tool(s):
{"batch_summary": {"failed": 0, "successful": 0, "total_tools": 0}, "results": []}
After fixing Bug 1 only [locally] (Bug 2 surfaces):
All 6 sub-tool calls fail with ConcurrencyException:
2026-03-10 17:26:33,510 - strands.agent - INFO - Tool #1: batch
Error executing tool 'current_time': Direct tool call cannot be made while the agent is
in the middle of an invocation. Set record_direct_tool_call=False to allow direct tool
calls during agent invocation.
Error executing tool 'current_time': Direct tool call cannot be made while the agent is
in the middle of an invocation. Set record_direct_tool_call=False to allow direct tool
calls during agent invocation.
... (repeated for all 6 invocations)
Additional Context
No response
Possible Solution
Bug 1: invocations read from wrong source (line 97)
Root Cause
The bug is in src/strands_tools/batch.py line 97:
def batch(tool: ToolUse, **kwargs) -> ToolResult:
agent = kwargs.get("agent")
invocations = kwargs.get("invocations", []) # ← BUG: always returns []The batch tool is a module-based tool (uses TOOL_SPEC + function, not @tool decorator), so it is loaded as a PythonAgentTool. When PythonAgentTool.stream() calls the tool function, it passes:
# strands/tools/tools.py line 259
result = await asyncio.to_thread(self._tool_func, tool_use, **invocation_state)tool_use(first arg →toolparam): Contains{"toolUseId": "...", "name": "batch", "input": {"invocations": [...]}}**invocation_state(→**kwargs): Contains{"agent": <Agent>, "model": ..., "messages": ..., "system_prompt": ..., "tool_config": ...}
So kwargs has agent, model, messages, etc. — but NOT invocations. The invocations array is in tool["input"]["invocations"].
Compare this with DecoratedFunctionTool.stream() (used by @tool decorated functions like current_time) which correctly extracts tool_use.get("input", {}) and passes validated input to the function.
Current behavior (line 97)
invocations = kwargs.get("invocations", [])Proposed Fix (line 97)
invocations = tool.get("input", {}).get("invocations", [])Bug 2: Sub-tool calls fail with ConcurrencyException (line 112)
Root Cause
After fixing Bug 1, the batch tool correctly iterates over invocations and calls sub-tools via agent.tool.<name>(**arguments) on line 112:
result = tool_fn(**arguments) # ← BUG: missing record_direct_tool_call=FalseSince batch is called during an active agent invocation, the agent holds its invocation lock. When agent.tool.current_time(...) is called, the SDK's ToolCaller (strands/tools/_caller.py lines 88-96) tries to acquire the same lock and raises:
ConcurrencyException: Direct tool call cannot be made while the agent is in the middle
of an invocation. Set record_direct_tool_call=False to allow direct tool calls during
agent invocation.
The ToolCaller accepts record_direct_tool_call=False to skip the lock (and skip recording in message history), which is exactly what batch sub-tool calls need.
Current behavior (line 112)
result = tool_fn(**arguments)Proposed Fix (line 112)
result = tool_fn(record_direct_tool_call=False, **arguments)Summary of all changes needed in src/strands_tools/batch.py
- invocations = kwargs.get("invocations", [])
+ invocations = tool.get("input", {}).get("invocations", [])- result = tool_fn(**arguments)
+ result = tool_fn(record_direct_tool_call=False, **arguments)Related Issues
- Bug 1 may also affect other module-based tools (
TOOL_SPEC+ function pattern) that read their input arguments fromkwargsinstead oftool["input"]. - Bug 2 would affect any tool that makes direct
agent.tool.<name>()calls during an active agent invocation.
PFB Screenshot after fixing both bugs:
Related Issues
No response