Skip to content

fix(tools): raise ToolUsageError instead of bare raise for non-dict arguments#6495

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

fix(tools): raise ToolUsageError instead of bare raise for non-dict arguments#6495
ashusnapx wants to merge 1 commit into
crewAIInc:mainfrom
ashusnapx:fix/tool-usage-bare-raise

Conversation

@ashusnapx

@ashusnapx ashusnapx commented Jul 9, 2026

Copy link
Copy Markdown

Summary

Fixes RuntimeError: No active exception to re-raise in ToolUsage._original_tool_calling() when _validate_tool_input returns a non-dict and raise_error=True.

Closes #6430

Problem

_original_tool_calling() at tool_usage.py:853 had a bare raise outside any except block:

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

When this path was hit with raise_error=True, Python raised RuntimeError: No active exception to re-raise instead of the intended ToolUsageError. The _tool_calling() fallback relies on catching a meaningful exception to trigger its retry logic, so this produced a confusing RuntimeError.

Also flagged by ruff check --select PLE0704.

Fix

Replace bare raise with explicit raise ToolUsageError(...):

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

The except block above (line 846-848) correctly uses bare raise inside an active exception context — left unchanged.

Tests (4 new)

Test What it verifies
test_original_tool_calling_non_dict_raises_tool_usage_error raise_error=True raises ToolUsageError, not RuntimeError
test_original_tool_calling_non_dict_returns_error raise_error=False returns ToolUsageError
test_tool_calling_fallback_on_non_dict Full _tool_calling flow falls back gracefully
test_non_dict_raises_not_runtime_error Exception type is ToolUsageError, not RuntimeError

All 32 tests in test_tool_usage.py pass. ruff check --select PLE0704 clean.

Verification

pytest lib/crewai/tests/tools/test_tool_usage.py -v
ruff check lib/crewai/src/crewai/tools/tool_usage.py --select PLE0704

Summary by CodeRabbit

  • Bug Fixes

    • Improved error handling when tool input can’t be parsed into valid arguments, so users now get a clear tool usage error instead of an unexpected crash.
    • Preserved fallback behavior so invalid tool input is reported consistently rather than stopping execution abruptly.
  • Tests

    • Added regression coverage for invalid tool input cases to verify the correct error type and message are returned in both strict and non-strict flows.

…rguments

Closes crewAIInc#6430

_original_tool_calling() contained a bare `raise` on the non-dict
arguments path (line 853) outside any except block. When
_validate_tool_input returned a non-dict and raise_error=True, this
produced RuntimeError: No active exception to re-raise instead of the
intended ToolUsageError.

Replace with explicit `raise ToolUsageError(...)`. The except block
above (line 846-848) correctly uses bare `raise` inside an active
exception context — left unchanged.

Also resolves ruff PLE0704 (bare raise not inside exception handler).

Tests: 4 new regression tests covering the non-dict branch with both
raise_error settings, the _tool_calling fallback flow, and verification
that RuntimeError is never raised. All 32 tests in test_tool_usage.py
pass. ruff clean.
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 21077f8a-20f4-4527-867b-2ceeda2fe014

📥 Commits

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

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

📝 Walkthrough

Walkthrough

The _original_tool_calling method in ToolUsage now raises ToolUsageError with the localized tool_arguments_error message when parsed tool arguments are not a dict and raise_error=True, replacing a bare raise that previously caused a RuntimeError. Regression tests were added covering this behavior.

Changes

Bare Raise Fix

Layer / File(s) Summary
Raise ToolUsageError for non-dict arguments
lib/crewai/src/crewai/tools/tool_usage.py
_original_tool_calling now raises ToolUsageError with the tool_arguments_error i18n message instead of executing a bare raise when parsed arguments are not a dict and raise_error=True.
Regression tests for non-dict input
lib/crewai/tests/tools/test_tool_usage.py
Adds _make_tool_usage_for_non_dict_test() helper and four tests verifying _original_tool_calling raises/returns ToolUsageError (not RuntimeError) for non-dict parsed input, and that _tool_calling falls back correctly.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 62.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main fix: replacing a bare raise with ToolUsageError for non-dict tool arguments.
Linked Issues check ✅ Passed The code and regression tests address #6430 by raising ToolUsageError, preserving fallback behavior, and covering the non-dict path.
Out of Scope Changes check ✅ Passed The changes stay within the bug fix scope and add only targeted regression tests, with no unrelated behavior changes evident.
✨ 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