From ee81b6ef6c7f47374329482d5c8327ee27ebe330 Mon Sep 17 00:00:00 2001 From: nicolas-bezdolya Date: Wed, 1 Apr 2026 02:05:45 -0300 Subject: [PATCH] fix: set StatusCode.ERROR on tool spans when tool result status is error When a tool raises an exception, Strands catches it and converts it to a ToolResult dict with status='error'. The original exception object is lost before end_tool_call_span is called, so the span always gets StatusCode.OK. This fix synthesizes an Exception from the error content in the tool result when no explicit error is passed, ensuring the span correctly gets StatusCode.ERROR. This is critical for observability backends like Langfuse that rely on span status codes for error detection. Fixes #2016 --- src/strands/telemetry/tracer.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/strands/telemetry/tracer.py b/src/strands/telemetry/tracer.py index 85083722e..14139e254 100644 --- a/src/strands/telemetry/tracer.py +++ b/src/strands/telemetry/tracer.py @@ -501,6 +501,12 @@ def end_tool_call_span(self, span: Span, tool_result: ToolResult | None, error: }, ) + # If no explicit error but tool_result indicates an error, synthesize one so the span gets StatusCode.ERROR + if error is None and tool_result is not None and tool_result.get("status") == "error": + content = tool_result.get("content", []) + error_message = content[0].get("text", "Tool call failed") if content else "Tool call failed" + error = Exception(error_message) + self._end_span(span, attributes, error) def start_event_loop_cycle_span(