-
Notifications
You must be signed in to change notification settings - Fork 753
[BUG] Strands Swallows Tool Call Errors #2016
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.33
Python Version
3.12
Operating System
macOS/AL2023
Installation Method
pip
Steps to Reproduce
The exception flow is:
- Tool raises →
_stream()catches it at ~line 259 _stream()buildserror_result = {"status": "error", ...}and yieldsToolResultEvent_stream_with_trace()receives theToolResultEventand callsend_tool_call_span(span, result)— without theerrorparam- In
tracer.py,end_tool_call_span()falls into theelsebranch →span.set_status(StatusCode.OK)
The exception object is lost before end_tool_call_span is ever called.
gen_ai.tool.status: "error" attribute IS correctly set — but the span StatusCode remains OK.
Expected Behavior
Tool spans should have StatusCode.ERROR when result["status"] == "error".
This is critical because Langfuse relies on this error code to raise alarms/statistics on failed tool calls. Without this, it is difficult to see which tools failed.
Actual Behavior
When a tool raises, Strands catches it and produces this ToolResult dict:
1{
2 "toolUseId": "",
3 "status": "error", # ← error IS here
4 "content": [{"text": "Error: ValueError - some message"}] # ← message too
5}This is wrapped in a ToolResultEvent and yielded. The original exception object is gone — only the dict survives.
So for the GitHub issue's Actual Behavior section:The tool span always gets StatusCode.OK. The error is recorded — but only as a string in result["content"][0]["text"] and gen_ai.tool.status: "error" attribute. The Python exception object is dropped, so end_tool_call_span never sees it and always calls span.set_status(StatusCode.OK).
Additional Context
No response
Possible Solution
No response
Related Issues
No response