Skip to content

fix(tools): raise ToolUsageError instead of bare raise on non-dict args#6486

Open
HumphreySun98 wants to merge 1 commit into
crewAIInc:mainfrom
HumphreySun98:fix/tool-usage-bare-raise
Open

fix(tools): raise ToolUsageError instead of bare raise on non-dict args#6486
HumphreySun98 wants to merge 1 commit into
crewAIInc:mainfrom
HumphreySun98:fix/tool-usage-bare-raise

Conversation

@HumphreySun98

Copy link
Copy Markdown

Problem

ToolUsage._original_tool_calling has a bare raise on the non-dict path, which sits outside the preceding try/except:

try:
    arguments = self._validate_tool_input(self.action.tool_input)
except Exception:
    if raise_error:
        raise            # OK — re-raises the active exception
    return ToolUsageError(...)

if not isinstance(arguments, dict):
    if raise_error:
        raise            # BUG — no active exception here
    return ToolUsageError(...)

_tool_calling() calls this with raise_error=True, so if _validate_tool_input ever returns a non-dict, the bare raise fails with RuntimeError: No active exception to re-raise — masking the intended tool-arguments error. It's a latent landmine today (that helper currently always returns a dict or raises), but it's still incorrect.

Fix

Raise the intended ToolUsageError explicitly:

if not isinstance(arguments, dict):
    error = ToolUsageError(f"{I18N_DEFAULT.errors('tool_arguments_error')}")
    if raise_error:
        raise error
    return error

The bare raise at the earlier site (inside except) is correct and left unchanged.

Tests

Added two tests in test_tool_usage.py (mock _validate_tool_input → non-dict): raise_error=True raises ToolUsageError (not RuntimeError), and raise_error=False returns a ToolUsageError. Verified failing-without/passing-with the fix; full test_tool_usage.py (30) green; ruff + mypy clean.

Fixes #6430


This PR was authored with Claude Code. Per CONTRIBUTING.md, AI-generated contributions require the llm-generated label — I don't have triage permission to set it, so could a maintainer please add it? 🤖 Generated with Claude Code

_original_tool_calling had a bare `raise` on the `not isinstance(arguments,
dict)` path, which is outside the preceding try/except — so with
raise_error=True it fails with "RuntimeError: No active exception to re-raise"
instead of surfacing the intended tool-arguments error. Raise the
ToolUsageError explicitly.

Fixes crewAIInc#6430

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4065675a-9033-4289-aa49-db4ccff5d164

📥 Commits

Reviewing files that changed from the base of the PR and between 289686a and 5a33751.

📒 Files selected for processing (2)
  • lib/crewai/src/crewai/tools/tool_usage.py
  • lib/crewai/tests/tools/test_tool_usage.py

📝 Walkthrough

Walkthrough

Fixed a bare raise statement in ToolUsage._original_tool_calling that caused a RuntimeError instead of a meaningful error when tool-validated arguments are not a dictionary. Now a ToolUsageError is explicitly constructed and raised, or returned when raise_error is False. Added corresponding tests.

Changes

Bare raise fix and tests

Layer / File(s) Summary
Fix bare raise and add regression tests
lib/crewai/src/crewai/tools/tool_usage.py, lib/crewai/tests/tools/test_tool_usage.py
When validated arguments are not a dict, a ToolUsageError is now explicitly constructed and raised (instead of a bare raise) when raise_error=True, or returned when raise_error=False; tests import ToolUsageError, add a _tool_usage_for_calling() helper, and verify both branches.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main fix: replacing a bare raise with ToolUsageError for non-dict tool args.
Description check ✅ Passed The description matches the code changes and explains the bug, fix, and regression tests.
Linked Issues check ✅ Passed The PR implements the required ToolUsageError behavior and adds tests for both raise_error paths, matching #6430.
Out of Scope Changes check ✅ Passed The changes stay focused on the bug fix and its tests, with no unrelated code paths or features introduced.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Bare raise in ToolUsage._original_tool_calling causes RuntimeError instead of ToolUsageError

1 participant