From 8b75f332b62c0ac3930b74e504c3c5b7a22457e5 Mon Sep 17 00:00:00 2001 From: Aniket <127662135+jasoncobra3@users.noreply.github.com> Date: Sat, 20 Jun 2026 22:30:29 +0530 Subject: [PATCH] fix: append traceback to tool execution error messages Closes #6262 Tool exceptions were caught and replaced with generic error strings like 'Error executing tool: {e}', discarding the original traceback and making debugging impossible. Fixed by appending traceback.format_exc(limit=5) to all tool execution error returns across 4 files: - agents/crew_agent_executor.py: main tool execution handler - experimental/agent_executor.py: 4 exception handlers including printer output and action.result - utilities/agent_utils.py: native tool call handler - llm.py: LLMCallFailedEvent and ToolUsageErrorEvent The 'Error executing tool:' prefix is preserved to avoid breaking existing parsing logic. traceback.format_exc(limit=5) limits output to 5 frames to avoid flooding LLM context windows. Pre-existing test failures (RuntimeError: Network is disabled) confirmed unrelated via git stash verification on Windows Python 3.13 with pytest-recording. --- lib/crewai/src/crewai/agents/crew_agent_executor.py | 3 ++- lib/crewai/src/crewai/experimental/agent_executor.py | 11 ++++++----- lib/crewai/src/crewai/llm.py | 7 ++++--- lib/crewai/src/crewai/utilities/agent_utils.py | 3 ++- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/crewai/src/crewai/agents/crew_agent_executor.py b/lib/crewai/src/crewai/agents/crew_agent_executor.py index de2315e3a9..c93f0c6242 100644 --- a/lib/crewai/src/crewai/agents/crew_agent_executor.py +++ b/lib/crewai/src/crewai/agents/crew_agent_executor.py @@ -13,6 +13,7 @@ import contextvars import inspect import logging +import traceback from typing import TYPE_CHECKING, Annotated, Any, Literal, cast import warnings @@ -1006,7 +1007,7 @@ def _execute_single_native_tool_call( result = format_native_tool_output_for_agent(output_tool, raw_result) except Exception as e: - result = f"Error executing tool: {e}" + result = f"Error executing tool: {e}\nTraceback:\n{traceback.format_exc(limit=5)}" raw_tool_result = result if self.task: self.task.increment_tools_errors() diff --git a/lib/crewai/src/crewai/experimental/agent_executor.py b/lib/crewai/src/crewai/experimental/agent_executor.py index 303330dc6a..131e98421d 100644 --- a/lib/crewai/src/crewai/experimental/agent_executor.py +++ b/lib/crewai/src/crewai/experimental/agent_executor.py @@ -9,6 +9,7 @@ import inspect import json import threading +import traceback from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast from uuid import uuid4 @@ -1611,13 +1612,13 @@ def execute_tool_action(self) -> Literal["tool_completed", "tool_result_is_final ) except Exception as e: if self.agent and self.agent.verbose: - PRINTER.print(content=f"Error in tool execution: {e}", color="red") + PRINTER.print(content=f"Error in tool execution: {e}\n{traceback.format_exc(limit=5)}", color="red") if self.task: self.task.increment_tools_errors() - error_observation = f"\nObservation: Error executing tool: {e}" + error_observation = f"\nObservation: Error executing tool: {e}\nTraceback:\n{traceback.format_exc(limit=5)}" action.text += error_observation - action.result = str(e) + action.result = str(e) + f"\nTraceback:\n{traceback.format_exc(limit=5)}" self._append_message_to_state(action.text) reasoning_prompt = I18N_DEFAULT.slice("post_tool_reasoning") @@ -1736,7 +1737,7 @@ def execute_native_tool( ordered_results[idx] = { "call_id": call_id, "func_name": func_name, - "result": f"Error executing tool: {e}", + "result": f"Error executing tool: {e}\nTraceback:\n{traceback.format_exc(limit=5)}", "from_cache": False, "original_tool": None, } @@ -1999,7 +2000,7 @@ def _execute_single_native_tool_call(self, tool_call: Any) -> dict[str, Any]: output_tool, raw_result ) except Exception as e: - result = f"Error executing tool: {e}" + result = f"Error executing tool: {e}\nTraceback:\n{traceback.format_exc(limit=5)}" raw_tool_result = result if self.task: self.task.increment_tools_errors() diff --git a/lib/crewai/src/crewai/llm.py b/lib/crewai/src/crewai/llm.py index 153bbd2d73..50b98598ff 100644 --- a/lib/crewai/src/crewai/llm.py +++ b/lib/crewai/src/crewai/llm.py @@ -14,6 +14,7 @@ TypedDict, cast, ) +import traceback from dotenv import load_dotenv from pydantic import BaseModel, Field, model_validator @@ -1755,11 +1756,11 @@ def _handle_tool_call( return result except Exception as e: fn = available_functions.get(function_name, lambda: None) - logging.error(f"Error executing function '{function_name}': {e}") + logging.error(f"Error executing function '{function_name}': {e}\n{traceback.format_exc(limit=5)}") crewai_event_bus.emit( self, event=LLMCallFailedEvent( - error=f"Tool execution error: {e!s}", + error=f"Tool execution error: {e!s}\nTraceback:\n{traceback.format_exc(limit=5)}", from_task=from_task, from_agent=from_agent, call_id=get_current_call_id(), @@ -1770,7 +1771,7 @@ def _handle_tool_call( event=ToolUsageErrorEvent( tool_name=function_name, tool_args=function_args, - error=f"Tool execution error: {e!s}", + error=f"Tool execution error: {e!s}\nTraceback:\n{traceback.format_exc(limit=5)}", from_task=from_task, from_agent=from_agent, ), diff --git a/lib/crewai/src/crewai/utilities/agent_utils.py b/lib/crewai/src/crewai/utilities/agent_utils.py index e933a38a80..db97214cbb 100644 --- a/lib/crewai/src/crewai/utilities/agent_utils.py +++ b/lib/crewai/src/crewai/utilities/agent_utils.py @@ -10,6 +10,7 @@ import inspect import json import re +import traceback from typing import TYPE_CHECKING, Any, Final, Literal, TypedDict from crewai_core.printer import PRINTER, ColoredText, Printer @@ -1546,7 +1547,7 @@ def execute_single_native_tool_call( result = format_native_tool_output_for_agent(output_tool, raw_result) except Exception as e: - result = f"Error executing tool: {e}" + result = f"Error executing tool: {e}\nTraceback:\n{traceback.format_exc(limit=5)}" raw_tool_result = result if task: task.increment_tools_errors()