BUG: [error-handling] Silent error suppression in cli_bootstrap._build_facadecontextlib.suppress(Exception) hides DI container wiring failures #5847

Open
opened 2026-04-09 10:41:17 +00:00 by HAL9000 · 2 comments
Owner

Metadata

  • Branch: fix/cli-bootstrap-suppress-exception
  • Commit Message: fix(a2a): replace contextlib.suppress(Exception) in _build_facade with structured error logging
  • Milestone: (backlog — see note below)
  • Parent Epic: #5502

Background

src/cleveragents/a2a/cli_bootstrap.py uses contextlib.suppress(Exception) to wrap each call to the dependency injection container in _build_facade. This is a dangerous pattern that silently swallows any exception during service resolution — including ModuleNotFoundError, AttributeError, or application-specific configuration errors. The function provides no logging or alternative error handling, effectively hiding critical configuration problems.

This is a direct violation of the CONTRIBUTING.md error handling rule:

CRITICAL: Do not suppress errors. Let exceptions propagate to top-level execution.

A similar pattern was identified in plan.py (issue #5693). This issue covers the same anti-pattern in cli_bootstrap.py.

Evidence

# src/cleveragents/a2a/cli_bootstrap.py lines 39-49
with contextlib.suppress(Exception):
    services["plan_lifecycle_service"] = container.plan_lifecycle_service()

with contextlib.suppress(Exception):
    services["session_service"] = container.session_service()

with contextlib.suppress(Exception):
    services["resource_registry_service"] = container.resource_registry_service()

with contextlib.suppress(Exception):
    services["tool_registry"] = container.tool_registry()

Expected Behavior

The _build_facade function should not suppress exceptions. If a service cannot be resolved from the container, the function should either:

  1. Log the exception clearly using structlog to alert developers of the configuration issue.
  2. Propagate the exception to fail fast, preventing the application from starting with a misconfigured facade.

Actual Behavior

Exceptions during service resolution are silently caught and ignored. The facade is created with missing services, and the application continues to run in a broken state. Failures in the DI container during service wiring are completely invisible to operators and developers.

Suggested Fix

Replace contextlib.suppress(Exception) with a try...except block that logs the exception with structlog:

import structlog

logger = structlog.get_logger(__name__)

try:
    services["plan_lifecycle_service"] = container.plan_lifecycle_service()
except Exception:
    logger.exception("failed_to_wire_service", service_name="plan_lifecycle_service")

Subtasks

  • Add structlog logger to cli_bootstrap.py
  • Replace all four contextlib.suppress(Exception) blocks with try...except blocks that log via structlog.exception()
  • Remove the import contextlib statement if no longer needed
  • Add/update unit tests to verify that service wiring failures are logged and not silently suppressed
  • Ensure all nox stages pass

Definition of Done

  • All four contextlib.suppress(Exception) blocks in _build_facade are replaced with structured error logging
  • A structlog logger is used to log exceptions at exception level with service_name context
  • Unit tests verify that wiring failures produce log output (not silent suppression)
  • All nox stages pass (nox -e lint, nox -e typecheck, nox -e unit_tests, nox -e integration_tests)
  • Coverage >= 97%
  • PR is merged and linked issue is closed

Backlog note: This issue was discovered during autonomous operation
on milestone v3.5.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

## Metadata - **Branch**: `fix/cli-bootstrap-suppress-exception` - **Commit Message**: `fix(a2a): replace contextlib.suppress(Exception) in _build_facade with structured error logging` - **Milestone**: *(backlog — see note below)* - **Parent Epic**: #5502 ## Background `src/cleveragents/a2a/cli_bootstrap.py` uses `contextlib.suppress(Exception)` to wrap each call to the dependency injection container in `_build_facade`. This is a dangerous pattern that silently swallows *any* exception during service resolution — including `ModuleNotFoundError`, `AttributeError`, or application-specific configuration errors. The function provides no logging or alternative error handling, effectively hiding critical configuration problems. This is a direct violation of the CONTRIBUTING.md error handling rule: > **CRITICAL: Do not suppress errors. Let exceptions propagate to top-level execution.** A similar pattern was identified in `plan.py` (issue #5693). This issue covers the same anti-pattern in `cli_bootstrap.py`. ## Evidence ```python # src/cleveragents/a2a/cli_bootstrap.py lines 39-49 with contextlib.suppress(Exception): services["plan_lifecycle_service"] = container.plan_lifecycle_service() with contextlib.suppress(Exception): services["session_service"] = container.session_service() with contextlib.suppress(Exception): services["resource_registry_service"] = container.resource_registry_service() with contextlib.suppress(Exception): services["tool_registry"] = container.tool_registry() ``` ## Expected Behavior The `_build_facade` function should not suppress exceptions. If a service cannot be resolved from the container, the function should either: 1. Log the exception clearly using `structlog` to alert developers of the configuration issue. 2. Propagate the exception to fail fast, preventing the application from starting with a misconfigured facade. ## Actual Behavior Exceptions during service resolution are silently caught and ignored. The facade is created with missing services, and the application continues to run in a broken state. Failures in the DI container during service wiring are completely invisible to operators and developers. ## Suggested Fix Replace `contextlib.suppress(Exception)` with a `try...except` block that logs the exception with `structlog`: ```python import structlog logger = structlog.get_logger(__name__) try: services["plan_lifecycle_service"] = container.plan_lifecycle_service() except Exception: logger.exception("failed_to_wire_service", service_name="plan_lifecycle_service") ``` ## Subtasks - [ ] Add `structlog` logger to `cli_bootstrap.py` - [ ] Replace all four `contextlib.suppress(Exception)` blocks with `try...except` blocks that log via `structlog.exception()` - [ ] Remove the `import contextlib` statement if no longer needed - [ ] Add/update unit tests to verify that service wiring failures are logged and not silently suppressed - [ ] Ensure all nox stages pass ## Definition of Done - [ ] All four `contextlib.suppress(Exception)` blocks in `_build_facade` are replaced with structured error logging - [ ] A `structlog` logger is used to log exceptions at `exception` level with `service_name` context - [ ] Unit tests verify that wiring failures produce log output (not silent suppression) - [ ] All nox stages pass (`nox -e lint`, `nox -e typecheck`, `nox -e unit_tests`, `nox -e integration_tests`) - [ ] Coverage >= 97% - [ ] PR is merged and linked issue is closed > **Backlog note:** This issue was discovered during autonomous operation > on milestone v3.5.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

Issue triaged by project owner:

  • State: Verified
  • Priority: Medium — Silent error suppression with contextlib.suppress(Exception) in cli_bootstrap._build_facade is a dangerous anti-pattern per CONTRIBUTING.md. It hides DI container wiring failures, making debugging extremely difficult. This should be fixed to use structured error logging instead.
  • Milestone: None (backlog) — This is a code quality fix that doesn't block any milestone.
  • Story Points: 2 — S — Replacing contextlib.suppress(Exception) with structured error logging is a focused change, estimated 1-4 hours.
  • MoSCoW: MoSCoW/Should have — CONTRIBUTING.md explicitly states "Errors must not be suppressed. Exceptions should propagate to the top-level execution for centralized logging and handling." This violates that rule and should be fixed.
  • Parent Epic: #5502 (as noted in the issue body)

Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: project-owner

Issue triaged by project owner: - **State**: Verified - **Priority**: Medium — Silent error suppression with `contextlib.suppress(Exception)` in `cli_bootstrap._build_facade` is a dangerous anti-pattern per CONTRIBUTING.md. It hides DI container wiring failures, making debugging extremely difficult. This should be fixed to use structured error logging instead. - **Milestone**: None (backlog) — This is a code quality fix that doesn't block any milestone. - **Story Points**: 2 — S — Replacing `contextlib.suppress(Exception)` with structured error logging is a focused change, estimated 1-4 hours. - **MoSCoW**: MoSCoW/Should have — CONTRIBUTING.md explicitly states "Errors must not be suppressed. Exceptions should propagate to the top-level execution for centralized logging and handling." This violates that rule and should be fixed. - **Parent Epic**: #5502 (as noted in the issue body) --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner
Author
Owner

Label compliance fix applied:

  • Added missing labels: State/Unverified, Type/Bug, Priority/Backlog
  • Reason: Issue had no State/, Type/, or Priority/* labels — CONTRIBUTING.md requires all three

Automated by CleverAgents Bot
Supervisor: Backlog Grooming | Agent: backlog-groomer

Label compliance fix applied: - Added missing labels: `State/Unverified`, `Type/Bug`, `Priority/Backlog` - Reason: Issue had no State/*, Type/*, or Priority/* labels — CONTRIBUTING.md requires all three --- **Automated by CleverAgents Bot** Supervisor: Backlog Grooming | Agent: backlog-groomer
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#5847
No description provided.