tool/actor_runtime: add failing test proving router path in _execute_tool_call swallows exceptions without recording ToolCallRecord #10383

Open
opened 2026-04-18 09:21:54 +00:00 by HAL9000 · 0 comments
Owner

Metadata

  • Commit Message: test(tool/actor_runtime): add failing test for router path exception swallowing in _execute_tool_call
  • Branch: test/actor-runtime-router-error-tdd

Background and Context

The ToolCallingRuntime._execute_tool_call() method has asymmetric error handling: the runner path has proper try/except blocks, but the router path (when self._router is not None) has none. This means any exception from self._router.route(payload) propagates uncaught, leaving the tool call unrecorded in the actor context and the ACTOR_ERRORED event unemitted. This TDD issue captures a failing test that proves the bug exists before the fix is applied.

Expected Behavior

A failing test exists at tests/unit/tool/test_actor_runtime_router_error.py that:

  • Is tagged @tdd_expected_fail
  • Fails with current code (proving the bug exists)
  • Passes after the corresponding bug fix is applied

Acceptance Criteria

  • Test file exists at tests/unit/tool/test_actor_runtime_router_error.py
  • Test is tagged @tdd_expected_fail and fails before the fix
  • Test passes after the bug fix in the corresponding Bug issue

Subtasks

  • Write the failing test
  • Verify it fails with current code
  • Link to the Bug issue

Definition of Done

This issue is complete when:

  • The test file exists and is tagged @tdd_expected_fail
  • The test fails with current code (proving the bug exists)
  • The corresponding Bug issue fix makes this test pass

TDD Test Specification

Tags

@tdd_issue @tdd_issue_1 @tdd_expected_fail

Test Description

Add a failing BDD/unit test that proves ToolCallingRuntime._execute_tool_call() does not record a ToolCallRecord or emit ACTOR_ERRORED when self._router.route(payload) raises an exception.

Expected Failing Test

# tests/unit/tool/test_actor_runtime_router_error.py
import pytest
from unittest.mock import MagicMock, patch
from cleveragents.tool.actor_runtime import ToolCallingRuntime, LLMToolCall
from cleveragents.tool.actor_context import ToolActorContext

def test_router_path_records_tool_call_on_exception():
    """When router.route() raises, _execute_tool_call should still record a ToolCallRecord."""
    registry = MagicMock()
    runner = MagicMock()
    llm_caller = MagicMock()
    router = MagicMock()
    router.route.side_effect = RuntimeError("Router failure")

    runtime = ToolCallingRuntime(
        registry=registry,
        runner=runner,
        llm_caller=llm_caller,
        router=router,
    )
    context = ToolActorContext(plan_id="test-plan", phase="execute")
    tool_call = LLMToolCall(name="my_tool", arguments={"key": "val"})

    # This should NOT raise - it should catch the error and record it
    result = runtime._execute_tool_call(tool_call, context, iteration=1)

    # Should have recorded a failed ToolCallRecord
    assert len(context.tool_call_history) == 1
    record = context.tool_call_history[0]
    assert record.success is False
    assert record.error is not None
    assert "Router failure" in record.error

Why This Test Currently Fails

In src/cleveragents/tool/actor_runtime.py, the router path (lines ~350-362) has no try/except:

if self._router is not None:
    payload = {"name": tool_call.name, "args": enriched_inputs, "type": "tool_call"}
    routed_result = self._router.route(payload)  # No error handling!
    elapsed_ms = (time.monotonic() - start) * 1000.0
    success = routed_result.result.success
    ...

If self._router.route(payload) raises, the exception propagates without:

  1. Recording a ToolCallRecord in the actor context
  2. Emitting ACTOR_ERRORED event
  3. Returning an error result to the LLM

The runner path (lines ~363-383) has proper try/except for both ToolError and Exception.


Automated by CleverAgents Bot
Agent: new-issue-creator

## Metadata - **Commit Message**: `test(tool/actor_runtime): add failing test for router path exception swallowing in _execute_tool_call` - **Branch**: `test/actor-runtime-router-error-tdd` ## Background and Context The `ToolCallingRuntime._execute_tool_call()` method has asymmetric error handling: the runner path has proper try/except blocks, but the router path (when `self._router is not None`) has none. This means any exception from `self._router.route(payload)` propagates uncaught, leaving the tool call unrecorded in the actor context and the `ACTOR_ERRORED` event unemitted. This TDD issue captures a failing test that proves the bug exists before the fix is applied. ## Expected Behavior A failing test exists at `tests/unit/tool/test_actor_runtime_router_error.py` that: - Is tagged `@tdd_expected_fail` - Fails with current code (proving the bug exists) - Passes after the corresponding bug fix is applied ## Acceptance Criteria - [ ] Test file exists at `tests/unit/tool/test_actor_runtime_router_error.py` - [ ] Test is tagged `@tdd_expected_fail` and fails before the fix - [ ] Test passes after the bug fix in the corresponding Bug issue ## Subtasks - [ ] Write the failing test - [ ] Verify it fails with current code - [ ] Link to the Bug issue ## Definition of Done This issue is complete when: - The test file exists and is tagged `@tdd_expected_fail` - The test fails with current code (proving the bug exists) - The corresponding Bug issue fix makes this test pass --- ## TDD Test Specification ### Tags @tdd_issue @tdd_issue_1 @tdd_expected_fail ### Test Description Add a failing BDD/unit test that proves `ToolCallingRuntime._execute_tool_call()` does not record a `ToolCallRecord` or emit `ACTOR_ERRORED` when `self._router.route(payload)` raises an exception. ### Expected Failing Test ```python # tests/unit/tool/test_actor_runtime_router_error.py import pytest from unittest.mock import MagicMock, patch from cleveragents.tool.actor_runtime import ToolCallingRuntime, LLMToolCall from cleveragents.tool.actor_context import ToolActorContext def test_router_path_records_tool_call_on_exception(): """When router.route() raises, _execute_tool_call should still record a ToolCallRecord.""" registry = MagicMock() runner = MagicMock() llm_caller = MagicMock() router = MagicMock() router.route.side_effect = RuntimeError("Router failure") runtime = ToolCallingRuntime( registry=registry, runner=runner, llm_caller=llm_caller, router=router, ) context = ToolActorContext(plan_id="test-plan", phase="execute") tool_call = LLMToolCall(name="my_tool", arguments={"key": "val"}) # This should NOT raise - it should catch the error and record it result = runtime._execute_tool_call(tool_call, context, iteration=1) # Should have recorded a failed ToolCallRecord assert len(context.tool_call_history) == 1 record = context.tool_call_history[0] assert record.success is False assert record.error is not None assert "Router failure" in record.error ``` ### Why This Test Currently Fails In `src/cleveragents/tool/actor_runtime.py`, the router path (lines ~350-362) has no try/except: ```python if self._router is not None: payload = {"name": tool_call.name, "args": enriched_inputs, "type": "tool_call"} routed_result = self._router.route(payload) # No error handling! elapsed_ms = (time.monotonic() - start) * 1000.0 success = routed_result.result.success ... ``` If `self._router.route(payload)` raises, the exception propagates without: 1. Recording a `ToolCallRecord` in the actor context 2. Emitting `ACTOR_ERRORED` event 3. Returning an error result to the LLM The runner path (lines ~363-383) has proper try/except for both `ToolError` and `Exception`. --- **Automated by CleverAgents Bot** Agent: new-issue-creator
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#10383
No description provided.