BUG-HUNT: [exit-code] action/actor/automation_profile commands use typer.Abort() on errors instead of typer.Exit(code=1) #7748

Open
opened 2026-04-12 03:23:19 +00:00 by HAL9000 · 3 comments
Owner

Bug Report: [Exit Code] Error Paths Use typer.Abort() (exit code 1 with '^C' output) Instead of typer.Exit(code=1)

Severity Assessment

  • Impact: Scripts checking exit codes receive exit code 1 regardless of whether an error is a user abort (Ctrl-C) or a real error (not-found, validation failure). The terminal also prints Aborted. which looks like a user interruption rather than a system error, confusing users and misleading CI logs.
  • Likelihood: Triggered on any failed action create/show/archive, actor add/update/remove/show/set-default, automation-profile add/remove/show operation.
  • Priority: Medium

Location

  • File: src/cleveragents/cli/commands/action.py
  • Function: create, list_actions, show, archive
  • Lines: 248-271, 328-343, 392-428, 460-469

Also:

  • File: src/cleveragents/cli/commands/actor.py
  • Lines: 655, 697, 778, 840, 941, 960 (all raise typer.Abort() from exc)
  • File: src/cleveragents/cli/commands/automation_profile.py
  • Lines: All error handlers in add_profile, remove_profile, list_profiles, show_profile

Description

typer.Abort() is the mechanism for user-initiated abort (Ctrl+C equivalent). When raised, Typer prints Aborted. to stderr and exits with code 1. Using it for error conditions is semantically incorrect: it signals an interactive abort rather than a program error, which:

  1. Makes the terminal output look like the user pressed Ctrl+C
  2. Prevents scripts from distinguishing 'user cancelled' from 'error'
  3. Is inconsistent with commands like session and repo that correctly use typer.Exit(code=1)

Evidence

# action.py lines 258-271 -- ALL error paths in create() use Abort
except FileNotFoundError as e:
    console.print(f"[red]Config file error:[/red] {e}")
    raise typer.Abort() from e      # BUG: should be typer.Exit(code=1)
except PydanticValidationError as e:
    console.print(f"[red]Schema validation error:[/red] {e}")
    raise typer.Abort() from e      # BUG
except ValueError as e:
    console.print(f"[red]Config validation error:[/red] {e}")
    raise typer.Abort() from e      # BUG
except ValidationError as e:
    console.print(f"[red]Validation Error:[/red] {e.message}")
    raise typer.Abort() from e      # BUG
except CleverAgentsError as e:
    console.print(f"[red]Error:[/red] {e.message}")
    raise typer.Abort() from e      # BUG

Compare with the correct pattern from session.py:

except SessionNotFoundError as exc:
    console.print(f"[red]Session not found:[/red] {session_id}")
    raise typer.Exit(1) from exc    # CORRECT

Expected Behavior

On error, commands should exit with a non-zero exit code (1 for general errors, 3 for not-found, etc.) without printing Aborted. to stderr.

Actual Behavior

  • Error message printed (correct)
  • Aborted. printed to stderr (incorrect -- looks like Ctrl+C)
  • Exit code is 1 (the right number, but for the wrong reason)

Suggested Fix

Replace all raise typer.Abort() from exc in error handlers of action.py, actor.py, and automation_profile.py with the appropriate:

raise typer.Exit(code=1) from exc  # or EXIT_ERROR from constants

For NotFoundError specifically, use EXIT_NOT_FOUND (code 3) per the constants module.

Category

exit-code

TDD Note

After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD.


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

## Bug Report: [Exit Code] Error Paths Use `typer.Abort()` (exit code 1 with '^C' output) Instead of `typer.Exit(code=1)` ### Severity Assessment - **Impact**: Scripts checking exit codes receive exit code 1 regardless of whether an error is a user abort (Ctrl-C) or a real error (not-found, validation failure). The terminal also prints `Aborted.` which looks like a user interruption rather than a system error, confusing users and misleading CI logs. - **Likelihood**: Triggered on any failed `action create/show/archive`, `actor add/update/remove/show/set-default`, `automation-profile add/remove/show` operation. - **Priority**: Medium ### Location - **File**: `src/cleveragents/cli/commands/action.py` - **Function**: `create`, `list_actions`, `show`, `archive` - **Lines**: 248-271, 328-343, 392-428, 460-469 Also: - **File**: `src/cleveragents/cli/commands/actor.py` - **Lines**: 655, 697, 778, 840, 941, 960 (all `raise typer.Abort() from exc`) - **File**: `src/cleveragents/cli/commands/automation_profile.py` - **Lines**: All error handlers in `add_profile`, `remove_profile`, `list_profiles`, `show_profile` ### Description `typer.Abort()` is the mechanism for user-initiated abort (Ctrl+C equivalent). When raised, Typer prints `Aborted.` to stderr and exits with code 1. Using it for error conditions is semantically incorrect: it signals an interactive abort rather than a program error, which: 1. Makes the terminal output look like the user pressed Ctrl+C 2. Prevents scripts from distinguishing 'user cancelled' from 'error' 3. Is inconsistent with commands like `session` and `repo` that correctly use `typer.Exit(code=1)` ### Evidence ```python # action.py lines 258-271 -- ALL error paths in create() use Abort except FileNotFoundError as e: console.print(f"[red]Config file error:[/red] {e}") raise typer.Abort() from e # BUG: should be typer.Exit(code=1) except PydanticValidationError as e: console.print(f"[red]Schema validation error:[/red] {e}") raise typer.Abort() from e # BUG except ValueError as e: console.print(f"[red]Config validation error:[/red] {e}") raise typer.Abort() from e # BUG except ValidationError as e: console.print(f"[red]Validation Error:[/red] {e.message}") raise typer.Abort() from e # BUG except CleverAgentsError as e: console.print(f"[red]Error:[/red] {e.message}") raise typer.Abort() from e # BUG ``` Compare with the correct pattern from `session.py`: ```python except SessionNotFoundError as exc: console.print(f"[red]Session not found:[/red] {session_id}") raise typer.Exit(1) from exc # CORRECT ``` ### Expected Behavior On error, commands should exit with a non-zero exit code (1 for general errors, 3 for not-found, etc.) without printing `Aborted.` to stderr. ### Actual Behavior - Error message printed (correct) - `Aborted.` printed to stderr (incorrect -- looks like Ctrl+C) - Exit code is 1 (the right number, but for the wrong reason) ### Suggested Fix Replace all `raise typer.Abort() from exc` in error handlers of `action.py`, `actor.py`, and `automation_profile.py` with the appropriate: ```python raise typer.Exit(code=1) from exc # or EXIT_ERROR from constants ``` For NotFoundError specifically, use `EXIT_NOT_FOUND` (code 3) per the constants module. ### Category exit-code ### TDD Note After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. --- **Automated by CleverAgents Bot** Supervisor: Bug Hunting | Agent: bug-hunter
HAL9000 added this to the v3.2.0 milestone 2026-04-12 03:44:27 +00:00
Author
Owner

Verified — Bug: commands use typer.Abort() instead of typer.Exit(code=1) on errors. MoSCoW: Should-have. Priority: Medium — exit code correctness.


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

✅ **Verified** — Bug: commands use typer.Abort() instead of typer.Exit(code=1) on errors. MoSCoW: Should-have. Priority: Medium — exit code correctness. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Author
Owner

Verified — Bug: commands use typer.Abort() instead of typer.Exit(code=1) on errors. MoSCoW: Should-have. Priority: Medium — exit code correctness.


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

✅ **Verified** — Bug: commands use typer.Abort() instead of typer.Exit(code=1) on errors. MoSCoW: Should-have. Priority: Medium — exit code correctness. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Author
Owner

Verified — Bug: commands use typer.Abort() instead of typer.Exit(code=1) on errors. MoSCoW: Should-have. Priority: Medium — exit code correctness.


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

✅ **Verified** — Bug: commands use typer.Abort() instead of typer.Exit(code=1) on errors. MoSCoW: Should-have. Priority: Medium — exit code correctness. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
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#7748
No description provided.