BUG-HUNT: [error-handling] _register_subcommands() prints raw traceback.format_exc() to stderr on import failure — internal stack frames leaked to users before exit #6643

Open
opened 2026-04-09 22:40:28 +00:00 by HAL9000 · 0 comments
Owner

Bug Report: [error-handling] — _register_subcommands() leaks raw traceback to stderr

Severity Assessment

  • Impact: When any CLI subcommand module fails to import (e.g. missing optional dependency, corrupted install, circular import), the full Python traceback is printed to stderr via traceback.format_exc() before the process exits with code 1. This exposes internal file paths, module structure, and possibly sensitive import-time values to any user or automated system capturing stderr.
  • Likelihood: Triggers on every partial or broken installation, or if any new import-time side effect raises an exception. Particularly visible in CI/CD pipelines and container deployments.
  • Priority: Medium

Location

  • File: src/cleveragents/cli/main.py
  • Function: _register_subcommands()
  • Lines: 105–111

Description

The _register_subcommands() function catches any Exception during subcommand module import and then prints the raw traceback to the stderr console before calling raise SystemExit(1):

# src/cleveragents/cli/main.py, lines 80-111
def _register_subcommands() -> None:
    """Register CLI subcommands lazily to reduce startup time."""
    global _subcommands_registered
    if _subcommands_registered:
        return

    try:
        from cleveragents.cli.commands import (
            action,
            actor,
            ...
        )
        ...
    except Exception as exc:
        import traceback

        err = get_err_console()
        err.print(f"[red]Failed to register subcommands:[/red] {exc}")
        err.print(traceback.format_exc())     # ← FULL TRACEBACK PRINTED
        raise SystemExit(1) from exc

The project's standard approach to safe error display is wrap_unexpected(exc)classify_error()format_error_for_cli(), which:

  1. Stores only the last 3 traceback frames (not all frames)
  2. Applies redact_value() to scrub secrets
  3. Formats via structured ErrorCode output

This _register_subcommands handler bypasses all of that and prints the raw full traceback.

Evidence

# src/cleveragents/cli/main.py, lines 105-111
    except Exception as exc:
        import traceback

        err = get_err_console()
        err.print(f"[red]Failed to register subcommands:[/red] {exc}")
        err.print(traceback.format_exc())   # ← full, unredacted stack dump
        raise SystemExit(1) from exc

For comparison, the main() function's global exception handler at lines 826–835 correctly uses wrap_unexpected():

    except Exception as e:
        from cleveragents.core.error_handling import classify_error, wrap_unexpected

        err_console = get_err_console()
        safe = wrap_unexpected(e)
        info = classify_error(safe)
        err_console.print(
            f"[red]Error [{info.code.value}] {info.code.name}:[/red] {info.message}"
        )
        return 1

The _register_subcommands handler predates this pattern and was never updated.

Expected Behavior

On subcommand import failure, the CLI should print a short, user-friendly error message without exposing internal stack frames — consistent with how all other errors are handled:

Error [500] INTERNAL: Failed to load CLI commands. Please check your installation.

Actual Behavior

Users (and stdout captures) receive the full Python traceback:

Failed to register subcommands: No module named 'some_dependency'
Traceback (most recent call last):
  File "/path/to/cleveragents/cli/main.py", line 81, in _register_subcommands
    from cleveragents.cli.commands import (
  ...
  File "/path/to/cleveragents/cli/commands/actor.py", line 42, in <module>
    from cleveragents.some_dependency import something
ModuleNotFoundError: No module named 'some_dependency'

Suggested Fix

Replace the raw traceback.format_exc() call with the same pattern used in main():

    except Exception as exc:
        from cleveragents.core.error_handling import classify_error, wrap_unexpected

        err = get_err_console()
        safe = wrap_unexpected(
            exc,
            safe_message="Failed to load CLI commands. Please check your installation.",
        )
        info = classify_error(safe)
        err.print(
            f"[red]Error [{info.code.value}] {info.code.name}:[/red] {info.message}"
        )
        raise SystemExit(1) from exc

Category

error-handling / security

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.


Automated by CleverAgents Bot
Supervisor: Bug Hunting | Agent: bug-hunter

## Bug Report: [error-handling] — `_register_subcommands()` leaks raw traceback to stderr ### Severity Assessment - **Impact**: When any CLI subcommand module fails to import (e.g. missing optional dependency, corrupted install, circular import), the full Python traceback is printed to stderr via `traceback.format_exc()` before the process exits with code 1. This exposes internal file paths, module structure, and possibly sensitive import-time values to any user or automated system capturing stderr. - **Likelihood**: Triggers on every partial or broken installation, or if any new import-time side effect raises an exception. Particularly visible in CI/CD pipelines and container deployments. - **Priority**: Medium ### Location - **File**: `src/cleveragents/cli/main.py` - **Function**: `_register_subcommands()` - **Lines**: 105–111 ### Description The `_register_subcommands()` function catches any `Exception` during subcommand module import and then **prints the raw traceback** to the stderr console before calling `raise SystemExit(1)`: ```python # src/cleveragents/cli/main.py, lines 80-111 def _register_subcommands() -> None: """Register CLI subcommands lazily to reduce startup time.""" global _subcommands_registered if _subcommands_registered: return try: from cleveragents.cli.commands import ( action, actor, ... ) ... except Exception as exc: import traceback err = get_err_console() err.print(f"[red]Failed to register subcommands:[/red] {exc}") err.print(traceback.format_exc()) # ← FULL TRACEBACK PRINTED raise SystemExit(1) from exc ``` The project's standard approach to safe error display is `wrap_unexpected(exc)` → `classify_error()` → `format_error_for_cli()`, which: 1. Stores only the last 3 traceback frames (not all frames) 2. Applies `redact_value()` to scrub secrets 3. Formats via structured `ErrorCode` output This `_register_subcommands` handler bypasses all of that and prints the raw full traceback. ### Evidence ```python # src/cleveragents/cli/main.py, lines 105-111 except Exception as exc: import traceback err = get_err_console() err.print(f"[red]Failed to register subcommands:[/red] {exc}") err.print(traceback.format_exc()) # ← full, unredacted stack dump raise SystemExit(1) from exc ``` For comparison, the `main()` function's global exception handler at lines 826–835 correctly uses `wrap_unexpected()`: ```python except Exception as e: from cleveragents.core.error_handling import classify_error, wrap_unexpected err_console = get_err_console() safe = wrap_unexpected(e) info = classify_error(safe) err_console.print( f"[red]Error [{info.code.value}] {info.code.name}:[/red] {info.message}" ) return 1 ``` The `_register_subcommands` handler predates this pattern and was never updated. ### Expected Behavior On subcommand import failure, the CLI should print a short, user-friendly error message without exposing internal stack frames — consistent with how all other errors are handled: ``` Error [500] INTERNAL: Failed to load CLI commands. Please check your installation. ``` ### Actual Behavior Users (and stdout captures) receive the full Python traceback: ``` Failed to register subcommands: No module named 'some_dependency' Traceback (most recent call last): File "/path/to/cleveragents/cli/main.py", line 81, in _register_subcommands from cleveragents.cli.commands import ( ... File "/path/to/cleveragents/cli/commands/actor.py", line 42, in <module> from cleveragents.some_dependency import something ModuleNotFoundError: No module named 'some_dependency' ``` ### Suggested Fix Replace the raw `traceback.format_exc()` call with the same pattern used in `main()`: ```python except Exception as exc: from cleveragents.core.error_handling import classify_error, wrap_unexpected err = get_err_console() safe = wrap_unexpected( exc, safe_message="Failed to load CLI commands. Please check your installation.", ) info = classify_error(safe) err.print( f"[red]Error [{info.code.value}] {info.code.name}:[/red] {info.message}" ) raise SystemExit(1) from exc ``` ### Category error-handling / security ### 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. --- **Automated by CleverAgents Bot** Supervisor: Bug Hunting | Agent: bug-hunter
HAL9000 added this to the v3.2.0 milestone 2026-04-09 22:47:13 +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.

Dependencies

No dependencies set.

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