UAT: agents server serve --log-level <invalid> wraps BadParameter as unexpected exception — wrong exit code and error message #1971

Open
opened 2026-04-03 00:28:04 +00:00 by freemo · 1 comment
Owner

Metadata

  • Branch: fix/server-serve-bad-parameter-exit-code
  • Commit Message: fix(cli): propagate BadParameter from _normalize_log_level as Typer usage error (exit 2)
  • Milestone: v3.7.0
  • Parent Epic: #933

Background and Context

During UAT testing of the CLI server mode feature area (agents server serve command), an invalid --log-level value was passed to verify proper error handling and exit code behavior. The test is specified in features/server_cli_coverage_boost.feature:

Scenario: server_serve rejects invalid log level via Typer option parsing
    When I invoke server_serve through the CLI with invalid log level "LOUD"
    Then the CLI invocation should fail with exit code 2
    And the server CLI invocation output should contain "Invalid value for '--log-level'"

The _normalize_log_level function in src/cleveragents/cli/commands/server.py is used as a Typer callback parameter on the --log-level option. When it raises typer.BadParameter, Typer should handle this as a usage error (exit code 2, per EXIT_USAGE = 2 in src/cleveragents/cli/constants.py). However, the main() function in cli/main.py catches the exception before Typer can handle it properly, wrapping it with wrap_unexpected() which produces the wrong error message and exit code.

Found by: UAT tester uat-tester-3993055-1775170778

Current Behavior

$ agents server serve --log-level invalid
Wrapping unexpected exception: BadParameter: must be one of: critical, error, warning, info, debug, trace
Error [500] INTERNAL: An unexpected error occurred
Exit: 1
  • Exit code is 1 (internal error) instead of 2 (usage error)
  • Error message says "Wrapping unexpected exception: BadParameter" instead of "Invalid value for '--log-level'"
  • The BadParameter exception raised by the _normalize_log_level Typer callback is being caught by the main() function's generic exception handler (wrap_unexpected) instead of being propagated as a Typer usage error

Expected Behavior

Per the spec and the BDD scenario in features/server_cli_coverage_boost.feature:

  • Exit code 2 (usage error, per EXIT_USAGE = 2 in src/cleveragents/cli/constants.py)
  • Error message containing "Invalid value for '--log-level'"

Steps to Reproduce

agents server serve --log-level invalid
echo "Exit: $?"

Root Cause Analysis

The _normalize_log_level function in src/cleveragents/cli/commands/server.py raises typer.BadParameter when an invalid log level is provided. Typer is designed to catch BadParameter exceptions from option callbacks and convert them into usage errors (exit code 2) with the standard "Invalid value for '--log-level'" message format.

However, the main() function in src/cleveragents/cli/main.py has a generic exception handler that catches BadParameter before Typer's own error handling can process it, wrapping it with wrap_unexpected() and producing exit code 1 with an internal error message.

The fix must ensure that typer.BadParameter (and potentially other Typer-internal exceptions like typer.Exit, typer.Abort) are not caught by the generic exception handler in main(), allowing them to propagate correctly through the Typer framework.

Affected files:

  • src/cleveragents/cli/commands/server.py_normalize_log_level() callback raises typer.BadParameter
  • src/cleveragents/cli/main.pymain() function's exception handler wraps BadParameter as unexpected

Acceptance Criteria

  • agents server serve --log-level LOUD exits with code 2
  • The error output contains "Invalid value for '--log-level'"
  • typer.BadParameter raised in option callbacks is NOT caught by the generic wrap_unexpected handler in main()
  • Other valid --log-level values (e.g., info, debug) continue to work correctly
  • The BDD scenario server_serve rejects invalid log level via Typer option parsing passes

Subtasks

  • Identify all Typer-internal exception types (typer.BadParameter, typer.Exit, typer.Abort) that must not be swallowed by the generic handler in src/cleveragents/cli/main.py
  • Update the exception handler in main() to re-raise or exclude Typer-internal exceptions before the generic wrap_unexpected catch
  • Verify _normalize_log_level() in src/cleveragents/cli/commands/server.py raises typer.BadParameter correctly (no change expected, but confirm)
  • Tests (Behave): Ensure the scenario server_serve rejects invalid log level via Typer option parsing in features/server_cli_coverage_boost.feature passes
  • Tests (Behave): Add/verify step implementations for the failing scenario
  • Verify coverage >=97% via nox -s coverage_report
  • Run nox (all default sessions), fix any errors

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • agents server serve --log-level <invalid> exits with code 2 and outputs "Invalid value for '--log-level'".
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation.
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly.
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done.
  • All nox stages pass.
  • Coverage >= 97%.

Automated by CleverAgents Bot
Supervisor: Acting on behalf of: UAT Testing | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/server-serve-bad-parameter-exit-code` - **Commit Message**: `fix(cli): propagate BadParameter from _normalize_log_level as Typer usage error (exit 2)` - **Milestone**: v3.7.0 - **Parent Epic**: #933 ## Background and Context During UAT testing of the CLI server mode feature area (`agents server serve` command), an invalid `--log-level` value was passed to verify proper error handling and exit code behavior. The test is specified in `features/server_cli_coverage_boost.feature`: ```gherkin Scenario: server_serve rejects invalid log level via Typer option parsing When I invoke server_serve through the CLI with invalid log level "LOUD" Then the CLI invocation should fail with exit code 2 And the server CLI invocation output should contain "Invalid value for '--log-level'" ``` The `_normalize_log_level` function in `src/cleveragents/cli/commands/server.py` is used as a Typer `callback` parameter on the `--log-level` option. When it raises `typer.BadParameter`, Typer should handle this as a usage error (exit code 2, per `EXIT_USAGE = 2` in `src/cleveragents/cli/constants.py`). However, the `main()` function in `cli/main.py` catches the exception before Typer can handle it properly, wrapping it with `wrap_unexpected()` which produces the wrong error message and exit code. **Found by**: UAT tester `uat-tester-3993055-1775170778` ## Current Behavior ``` $ agents server serve --log-level invalid Wrapping unexpected exception: BadParameter: must be one of: critical, error, warning, info, debug, trace Error [500] INTERNAL: An unexpected error occurred Exit: 1 ``` - Exit code is **1** (internal error) instead of **2** (usage error) - Error message says `"Wrapping unexpected exception: BadParameter"` instead of `"Invalid value for '--log-level'"` - The `BadParameter` exception raised by the `_normalize_log_level` Typer callback is being caught by the `main()` function's generic exception handler (`wrap_unexpected`) instead of being propagated as a Typer usage error ## Expected Behavior Per the spec and the BDD scenario in `features/server_cli_coverage_boost.feature`: - Exit code **2** (usage error, per `EXIT_USAGE = 2` in `src/cleveragents/cli/constants.py`) - Error message containing `"Invalid value for '--log-level'"` ## Steps to Reproduce ```bash agents server serve --log-level invalid echo "Exit: $?" ``` ## Root Cause Analysis The `_normalize_log_level` function in `src/cleveragents/cli/commands/server.py` raises `typer.BadParameter` when an invalid log level is provided. Typer is designed to catch `BadParameter` exceptions from option callbacks and convert them into usage errors (exit code 2) with the standard `"Invalid value for '--log-level'"` message format. However, the `main()` function in `src/cleveragents/cli/main.py` has a generic exception handler that catches `BadParameter` before Typer's own error handling can process it, wrapping it with `wrap_unexpected()` and producing exit code 1 with an internal error message. The fix must ensure that `typer.BadParameter` (and potentially other Typer-internal exceptions like `typer.Exit`, `typer.Abort`) are **not** caught by the generic exception handler in `main()`, allowing them to propagate correctly through the Typer framework. **Affected files:** - `src/cleveragents/cli/commands/server.py` — `_normalize_log_level()` callback raises `typer.BadParameter` - `src/cleveragents/cli/main.py` — `main()` function's exception handler wraps `BadParameter` as unexpected ## Acceptance Criteria - [ ] `agents server serve --log-level LOUD` exits with code **2** - [ ] The error output contains `"Invalid value for '--log-level'"` - [ ] `typer.BadParameter` raised in option callbacks is NOT caught by the generic `wrap_unexpected` handler in `main()` - [ ] Other valid `--log-level` values (e.g., `info`, `debug`) continue to work correctly - [ ] The BDD scenario `server_serve rejects invalid log level via Typer option parsing` passes ## Subtasks - [ ] Identify all Typer-internal exception types (`typer.BadParameter`, `typer.Exit`, `typer.Abort`) that must not be swallowed by the generic handler in `src/cleveragents/cli/main.py` - [ ] Update the exception handler in `main()` to re-raise or exclude Typer-internal exceptions before the generic `wrap_unexpected` catch - [ ] Verify `_normalize_log_level()` in `src/cleveragents/cli/commands/server.py` raises `typer.BadParameter` correctly (no change expected, but confirm) - [ ] Tests (Behave): Ensure the scenario `server_serve rejects invalid log level via Typer option parsing` in `features/server_cli_coverage_boost.feature` passes - [ ] Tests (Behave): Add/verify step implementations for the failing scenario - [ ] Verify coverage >=97% via `nox -s coverage_report` - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - `agents server serve --log-level <invalid>` exits with code 2 and outputs `"Invalid value for '--log-level'"`. - A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation. - The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly. - The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done. - All nox stages pass. - Coverage >= 97%. --- **Automated by CleverAgents Bot** Supervisor: Acting on behalf of: UAT Testing | Agent: ca-new-issue-creator
freemo added this to the v3.7.0 milestone 2026-04-03 00:28:56 +00:00
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: Medium (confirmed — this is a CLI error handling issue, not a data loss or security concern)
  • Milestone: v3.7.0 (confirmed — server CLI is part of M8 TUI/Server scope)
  • MoSCoW: Could Have — while the exit code is technically wrong (1 instead of 2), the error is still surfaced to the user. This is a polish issue for CLI standards compliance, not a functional blocker. The v3.7.0 milestone description says to focus on M1-M6 first.
  • Parent Epic: #933 (A2A Protocol Compliance — the server serve command is part of the A2A server infrastructure)

Well-documented issue with clear root cause analysis and reproduction steps. Valid and actionable.


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

Issue triaged by project owner: - **State**: Verified - **Priority**: Medium (confirmed — this is a CLI error handling issue, not a data loss or security concern) - **Milestone**: v3.7.0 (confirmed — server CLI is part of M8 TUI/Server scope) - **MoSCoW**: Could Have — while the exit code is technically wrong (1 instead of 2), the error is still surfaced to the user. This is a polish issue for CLI standards compliance, not a functional blocker. The v3.7.0 milestone description says to focus on M1-M6 first. - **Parent Epic**: #933 (A2A Protocol Compliance — the server serve command is part of the A2A server infrastructure) Well-documented issue with clear root cause analysis and reproduction steps. Valid and actionable. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
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#1971
No description provided.