BUG-HUNT: [error-handling] map_domain_error may hide bugs by catching all non-CleverAgentsError exceptions #6013

Open
opened 2026-04-09 13:38:13 +00:00 by HAL9000 · 1 comment
Owner

Bug Report: [error-handling] — map_domain_error may hide bugs by catching all non-CleverAgentsError exceptions

Severity Assessment

  • Impact: Unexpected exceptions that are not subclasses of CleverAgentsError are silently caught and reported as generic "Internal Server Errors" to the client. This hides the original error type and traceback, making it significantly harder to debug underlying problems in the domain logic. A critical bug in a dependency could be masked as a simple internal error.
  • Likelihood: High. Any unexpected exception from a third-party library or a part of the domain that does not use the custom exception hierarchy will trigger this behavior.
  • Priority: Medium

Location

  • File: src/cleveragents/a2a/errors.py
  • Function/Class: map_domain_error
  • Lines: 138-140

Description

The map_domain_error function is designed to map domain-specific exceptions to standardized A2A error codes. It correctly handles exceptions that inherit from CleverAgentsError. However, the final return statement acts as a catch-all for any other exception type.

def map_domain_error(exc: Exception) -> tuple[int, str]:
    # ... (specific exception checks)
    if isinstance(exc, CleverAgentsError):
        return INTERNAL_ERROR, str(exc)
    return INTERNAL_ERROR, str(exc)

This final return statement will catch any exception that is not a subclass of CleverAgentsError and return a generic INTERNAL_ERROR. This is problematic because it swallows the original exception type and context, making it very difficult to identify and fix the root cause of the error.

Evidence

# src/cleveragents/a2a/errors.py

def map_domain_error(exc: Exception) -> tuple[int, str]:
    """Map a domain exception to an A2A error code and message.
    ...
    """
    if not isinstance(exc, Exception):
        raise TypeError("exc must be an Exception instance")

    if isinstance(exc, ResourceNotFoundError):
        return NOT_FOUND, str(exc)
    if isinstance(exc, ValidationError):
        return VALIDATION_ERROR, str(exc)
    if isinstance(exc, PlanError):
        return PLAN_ERROR, str(exc)
    if isinstance(exc, BusinessRuleViolation):
        return INVALID_STATE, str(exc)
    if isinstance(exc, AuthenticationError):
        return AUTH_ERROR, str(exc)
    if isinstance(exc, AuthorizationError):
        return FORBIDDEN, str(exc)
    if isinstance(exc, ConfigurationError):
        return CONFIGURATION_ERROR, str(exc)
    if isinstance(exc, CleverAgentsError):
        return INTERNAL_ERROR, str(exc)
    return INTERNAL_ERROR, str(exc)

Expected Behavior

Exceptions that are not part of the CleverAgentsError hierarchy should not be silently converted into a generic INTERNAL_ERROR. They should either be:

  1. Re-raised to be handled by a higher-level error handler that can log the full traceback.
  2. Handled explicitly to provide more context about the unexpected error.
  3. Logged with full details before returning the generic error.

A better approach would be to remove the final return statement and let unhandled exceptions propagate.

Actual Behavior

Any exception that is not a subclass of CleverAgentsError is caught and converted into a generic INTERNAL_ERROR, hiding the original cause of the error.

Suggested Fix

Remove the final return statement from the map_domain_error function. This will cause unhandled exceptions to propagate, which will then be caught by the global exception handler and logged with a full traceback.

def map_domain_error(exc: Exception) -> tuple[int, str]:
    # ... (specific exception checks)
    if isinstance(exc, CleverAgentsError):
        return INTERNAL_ERROR, str(exc)
    # Let unhandled exceptions propagate
    raise exc

Alternatively, if the intention is to always return a JSON-RPC compliant error, the error should be logged with its full traceback before returning the generic error.

Category

error-handling

TDD Note

After this bug issue is verified, a corresponding Type/Testing issue will be
created for TDD. The test will use tags: @tdd_issue, @tdd_issue_,
and @tdd_expected_fail to prove the bug exists before fixing it.

Metadata

  • Branch: fix/map-domain-error-hide-bugs
  • Commit Message: fix(a2a): re-raise non-CleverAgentsError exceptions in map_domain_error instead of silently converting to INTERNAL_ERROR
  • Milestone: None (backlog)
  • Parent Epic: #4949

Subtasks

  • Investigate the full call chain of map_domain_error to understand all callers and their error-handling expectations
  • Determine the correct fix: re-raise, log-then-return, or explicit handling
  • Update map_domain_error in src/cleveragents/a2a/errors.py to not silently swallow non-CleverAgentsError exceptions
  • Write a Behave unit test (tagged @tdd_issue, @tdd_issue_<N>) that demonstrates the bug
  • Verify all nox quality gates pass (nox -e lint, nox -e typecheck, nox -e unit_tests, nox -e coverage_report)

Definition of Done

  • map_domain_error no longer silently converts non-CleverAgentsError exceptions to a generic INTERNAL_ERROR
  • A Behave unit test exists that covers the corrected behavior
  • All nox stages pass
  • Coverage >= 97%
  • The associated PR is merged

Backlog note: This issue was discovered during autonomous operation
on milestone v3.6.0. It does not block milestone completion and has been
placed in the backlog for human review and future milestone assignment.


Automated by CleverAgents Bot
Supervisor: Bug Hunting | Agent: new-issue-creator

## Bug Report: [error-handling] — `map_domain_error` may hide bugs by catching all non-CleverAgentsError exceptions ### Severity Assessment - **Impact**: Unexpected exceptions that are not subclasses of `CleverAgentsError` are silently caught and reported as generic "Internal Server Errors" to the client. This hides the original error type and traceback, making it significantly harder to debug underlying problems in the domain logic. A critical bug in a dependency could be masked as a simple internal error. - **Likelihood**: High. Any unexpected exception from a third-party library or a part of the domain that does not use the custom exception hierarchy will trigger this behavior. - **Priority**: Medium ### Location - **File**: `src/cleveragents/a2a/errors.py` - **Function/Class**: `map_domain_error` - **Lines**: 138-140 ### Description The `map_domain_error` function is designed to map domain-specific exceptions to standardized A2A error codes. It correctly handles exceptions that inherit from `CleverAgentsError`. However, the final `return` statement acts as a catch-all for any other exception type. ```python def map_domain_error(exc: Exception) -> tuple[int, str]: # ... (specific exception checks) if isinstance(exc, CleverAgentsError): return INTERNAL_ERROR, str(exc) return INTERNAL_ERROR, str(exc) ``` This final `return` statement will catch any exception that is not a subclass of `CleverAgentsError` and return a generic `INTERNAL_ERROR`. This is problematic because it swallows the original exception type and context, making it very difficult to identify and fix the root cause of the error. ### Evidence ```python # src/cleveragents/a2a/errors.py def map_domain_error(exc: Exception) -> tuple[int, str]: """Map a domain exception to an A2A error code and message. ... """ if not isinstance(exc, Exception): raise TypeError("exc must be an Exception instance") if isinstance(exc, ResourceNotFoundError): return NOT_FOUND, str(exc) if isinstance(exc, ValidationError): return VALIDATION_ERROR, str(exc) if isinstance(exc, PlanError): return PLAN_ERROR, str(exc) if isinstance(exc, BusinessRuleViolation): return INVALID_STATE, str(exc) if isinstance(exc, AuthenticationError): return AUTH_ERROR, str(exc) if isinstance(exc, AuthorizationError): return FORBIDDEN, str(exc) if isinstance(exc, ConfigurationError): return CONFIGURATION_ERROR, str(exc) if isinstance(exc, CleverAgentsError): return INTERNAL_ERROR, str(exc) return INTERNAL_ERROR, str(exc) ``` ### Expected Behavior Exceptions that are not part of the `CleverAgentsError` hierarchy should not be silently converted into a generic `INTERNAL_ERROR`. They should either be: 1. Re-raised to be handled by a higher-level error handler that can log the full traceback. 2. Handled explicitly to provide more context about the unexpected error. 3. Logged with full details before returning the generic error. A better approach would be to remove the final `return` statement and let unhandled exceptions propagate. ### Actual Behavior Any exception that is not a subclass of `CleverAgentsError` is caught and converted into a generic `INTERNAL_ERROR`, hiding the original cause of the error. ### Suggested Fix Remove the final `return` statement from the `map_domain_error` function. This will cause unhandled exceptions to propagate, which will then be caught by the global exception handler and logged with a full traceback. ```python def map_domain_error(exc: Exception) -> tuple[int, str]: # ... (specific exception checks) if isinstance(exc, CleverAgentsError): return INTERNAL_ERROR, str(exc) # Let unhandled exceptions propagate raise exc ``` Alternatively, if the intention is to always return a JSON-RPC compliant error, the error should be logged with its full traceback before returning the generic error. ### Category error-handling ### TDD Note After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. The test will use tags: @tdd_issue, @tdd_issue_<this-issue-number>, and @tdd_expected_fail to prove the bug exists before fixing it. ## Metadata - **Branch**: `fix/map-domain-error-hide-bugs` - **Commit Message**: `fix(a2a): re-raise non-CleverAgentsError exceptions in map_domain_error instead of silently converting to INTERNAL_ERROR` - **Milestone**: None (backlog) - **Parent Epic**: #4949 ## Subtasks - [ ] Investigate the full call chain of `map_domain_error` to understand all callers and their error-handling expectations - [ ] Determine the correct fix: re-raise, log-then-return, or explicit handling - [ ] Update `map_domain_error` in `src/cleveragents/a2a/errors.py` to not silently swallow non-`CleverAgentsError` exceptions - [ ] Write a Behave unit test (tagged `@tdd_issue`, `@tdd_issue_<N>`) that demonstrates the bug - [ ] Verify all nox quality gates pass (`nox -e lint`, `nox -e typecheck`, `nox -e unit_tests`, `nox -e coverage_report`) ## Definition of Done - [ ] `map_domain_error` no longer silently converts non-`CleverAgentsError` exceptions to a generic `INTERNAL_ERROR` - [ ] A Behave unit test exists that covers the corrected behavior - [ ] All nox stages pass - [ ] Coverage >= 97% - [ ] The associated PR is merged > **Backlog note:** This issue was discovered during autonomous operation > on milestone v3.6.0. It does not block milestone completion and has been > placed in the backlog for human review and future milestone assignment. --- **Automated by CleverAgents Bot** Supervisor: Bug Hunting | Agent: new-issue-creator
Author
Owner

🏷️ Label compliance fix applied by backlog groomer (cycle 64)

Added missing labels: State/Verified, Type/Bug, Priority/Backlog

This issue was missing the State/ and Type/ labels. Labels have been applied based on issue content (BUG-HUNT identified error-handling issue where non-CleverAgentsError exceptions are silently swallowed).


Automated by CleverAgents Bot
Supervisor: Label Management | Agent: forgejo-label-manager

🏷️ **Label compliance fix applied by backlog groomer (cycle 64)** Added missing labels: `State/Verified`, `Type/Bug`, `Priority/Backlog` This issue was missing the `State/` and `Type/` labels. Labels have been applied based on issue content (BUG-HUNT identified error-handling issue where non-CleverAgentsError exceptions are silently swallowed). --- **Automated by CleverAgents Bot** Supervisor: Label Management | Agent: forgejo-label-manager
HAL9000 added this to the v3.5.0 milestone 2026-04-09 15:36:16 +00:00
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.

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