Checks
Strands Version
Latest (unpinned via pip install strands-agents)
Python Version
3.13
Operating System
Amazon Linux (Bedrock AgentCore Runtime container)
Installation Method
pip
Steps to Reproduce
- Configure a Strands agent with
BedrockModel using model ID moonshotai.kimi-k2.5
- Register tools (e.g.,
web_search, output_slide)
- Call
agent.stream_async(user_message) and iterate over the stream
- The model successfully calls
web_search and receives results
- When the model attempts a subsequent tool call (e.g.,
output_slide), the event loop crashes
from strands import Agent
from strands.models.bedrock import BedrockModel
model = BedrockModel(model_id="moonshotai.kimi-k2.5")
agent = Agent(model=model, tools=[web_search, output_slide])
# This crashes during tool execution
stream = agent.stream_async("Search for X and create a slide")
async for event in stream:
print(event)
Expected Behavior
The event loop should handle the model's tool call response gracefully, even if the response format differs slightly from Claude models. At minimum, it should raise a descriptive error rather than an unhandled KeyError.
Actual Behavior
A KeyError: 'toolUse' is raised inside the event loop, crashing the entire stream:
Traceback (most recent call last):
File ".../strands/event_loop/event_loop.py", line 192, in event_loop_cycle
async for tool_event in tool_events:
yield tool_event
File ".../strands/event_loop/event_loop.py", line 535, in _handle_tool_execution
async for event in events:
yield event
File ".../strands/event_loop/event_loop.py", line 269, in recurse_event_loop
async for event in events:
yield event
File ".../strands/event_loop/event_loop.py", line 155, in event_loop_cycle
async for model_event in model_events:
if not isinstance(model_event, ModelStopReason):
yield model_event
File ".../strands/event_loop/event_loop.py", line 400, in _handle_model_execution
raise e
KeyError: 'toolUse'
This is then wrapped as EventLoopException: 'toolUse'.
Additional Context
- The issue occurs specifically with Kimi K2.5 (
moonshotai.kimi-k2.5) accessed via Amazon Bedrock. Claude models work fine.
- The first tool call (
web_search) succeeds and returns results. The crash happens on a subsequent tool call cycle.
- It appears the model returns a content block that Strands expects to contain a
toolUse key, but the key is missing or the structure differs from what the event loop parser expects.
- We observed this in production via CloudWatch Logs on Bedrock AgentCore Runtime (OTEL traces confirmed the sequence: successful
web_search -> crash on next tool call).
- As a workaround, we wrap the stream iteration in a
try/except to catch the EventLoopException and return a user-friendly error.
Possible Solution
The event loop could add a safety check (e.g., content.get("toolUse") instead of content["toolUse"]) or validate the content block structure before accessing the key. This would make Strands more resilient to non-Claude models that may produce slightly different response formats.
Related Issues
Checks
Strands Version
Latest (unpinned via
pip install strands-agents)Python Version
3.13
Operating System
Amazon Linux (Bedrock AgentCore Runtime container)
Installation Method
pip
Steps to Reproduce
BedrockModelusing model IDmoonshotai.kimi-k2.5web_search,output_slide)agent.stream_async(user_message)and iterate over the streamweb_searchand receives resultsoutput_slide), the event loop crashesExpected Behavior
The event loop should handle the model's tool call response gracefully, even if the response format differs slightly from Claude models. At minimum, it should raise a descriptive error rather than an unhandled
KeyError.Actual Behavior
A
KeyError: 'toolUse'is raised inside the event loop, crashing the entire stream:This is then wrapped as
EventLoopException: 'toolUse'.Additional Context
moonshotai.kimi-k2.5) accessed via Amazon Bedrock. Claude models work fine.web_search) succeeds and returns results. The crash happens on a subsequent tool call cycle.toolUsekey, but the key is missing or the structure differs from what the event loop parser expects.web_search-> crash on next tool call).try/exceptto catch theEventLoopExceptionand return a user-friendly error.Possible Solution
The event loop could add a safety check (e.g.,
content.get("toolUse")instead ofcontent["toolUse"]) or validate the content block structure before accessing the key. This would make Strands more resilient to non-Claude models that may produce slightly different response formats.Related Issues