Skip to content

[BUG] KeyError: 'toolUse' in event_loop when using Kimi K2.5 via Bedrock #1646

@minorun365

Description

@minorun365

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

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

  1. Configure a Strands agent with BedrockModel using model ID moonshotai.kimi-k2.5
  2. Register tools (e.g., web_search, output_slide)
  3. Call agent.stream_async(user_message) and iterate over the stream
  4. The model successfully calls web_search and receives results
  5. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions