UAT: agents repl silently exits with code 0 when no TTY is available — no user feedback #3972

Open
opened 2026-04-06 08:06:07 +00:00 by freemo · 0 comments
Owner

Metadata

  • Branch: fix/repl-no-tty-silent-exit
  • Commit Message: fix(cli): exit with code 1 and print error when repl invoked without TTY
  • Milestone: None (Backlog)
  • Parent Epic: #397

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


Bug Report

Feature Area: REPL and Interactive Mode
Severity: Medium — usability issue; users get no feedback when REPL fails to start
Found by: UAT tester (runtime testing)


Background and Context

The agents repl command provides an interactive REPL session for users to communicate with CleverAgents via the CLI. Per UX best practices and the principle of least surprise, any command that cannot fulfil its purpose should communicate the failure clearly and exit with a non-zero code. Currently, when agents repl is invoked without an interactive terminal (non-TTY context), it silently exits with code 0, giving users no indication of what happened or how to resolve it.

Additionally, the CLEVERAGENTS_FORCE_REPL=1 escape hatch exists but is completely undocumented in the --help output, making it undiscoverable.

Current Behavior

When agents repl is invoked without a TTY and without CLEVERAGENTS_FORCE_REPL=1:

  • Exit code: 0 (success — incorrect)
  • Output: Empty string (no output at all)
  • The REPL silently does nothing and exits cleanly

Root causesrc/cleveragents/cli/commands/repl.py, lines 841–843:

def repl_callback(...) -> None:
    """Start an interactive REPL session."""
    if sys.stdout.isatty() or os.environ.get("CLEVERAGENTS_FORCE_REPL"):
        raise SystemExit(run_repl(no_history=no_history, history_path=history_path))
    # BUG: No else clause — silently exits with code 0 when condition is False

Expected Behavior

When agents repl is invoked without a TTY and without CLEVERAGENTS_FORCE_REPL=1, the command should:

  1. Print a helpful error message to stderr, e.g.:
    Error: REPL requires an interactive terminal.
    Use CLEVERAGENTS_FORCE_REPL=1 to override.
    
  2. Exit with a non-zero exit code (e.g., 1) to signal failure

Steps to Reproduce

from typer.testing import CliRunner
from cleveragents.cli.main import app

runner = CliRunner()  # No TTY
result = runner.invoke(app, ["repl"])
print(f"Exit code: {result.exit_code}")  # 0  ← should be 1
print(f"Output: {repr(result.output)}")  # ''  ← should contain error message

Or from the command line:

echo "" | agents repl  # Piped input, no TTY
# No output, exit code 0  ← incorrect

Suggested Fix

Add an else clause to repl_callback in src/cleveragents/cli/commands/repl.py:

else:
    from rich.console import Console
    Console(stderr=True).print(
        "[red]Error:[/red] REPL requires an interactive terminal. "
        "Set [bold]CLEVERAGENTS_FORCE_REPL=1[/bold] to override."
    )
    raise SystemExit(1)

Also update the --help docstring to mention the TTY requirement and the CLEVERAGENTS_FORCE_REPL environment variable.


Subtasks

  • Add else clause to repl_callback in src/cleveragents/cli/commands/repl.py to print error to stderr and exit with code 1 when no TTY is available
  • Update --help docstring for agents repl to document the TTY requirement
  • Update --help docstring to document the CLEVERAGENTS_FORCE_REPL=1 override
  • Tests (Behave): Add scenario for agents repl invoked without TTY — assert exit code 1 and error message on stderr
  • Tests (Behave): Add scenario for agents repl with CLEVERAGENTS_FORCE_REPL=1 — assert REPL starts normally
  • 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.
  • 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: UAT Testing | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/repl-no-tty-silent-exit` - **Commit Message**: `fix(cli): exit with code 1 and print error when repl invoked without TTY` - **Milestone**: None (Backlog) - **Parent Epic**: #397 > **Backlog note:** This issue was discovered during autonomous operation > on milestone v3.7.0. It does not block milestone completion and has been > placed in the backlog for human review and future milestone assignment. --- ## Bug Report **Feature Area:** REPL and Interactive Mode **Severity:** Medium — usability issue; users get no feedback when REPL fails to start **Found by:** UAT tester (runtime testing) --- ## Background and Context The `agents repl` command provides an interactive REPL session for users to communicate with CleverAgents via the CLI. Per UX best practices and the principle of least surprise, any command that cannot fulfil its purpose should communicate the failure clearly and exit with a non-zero code. Currently, when `agents repl` is invoked without an interactive terminal (non-TTY context), it silently exits with code 0, giving users no indication of what happened or how to resolve it. Additionally, the `CLEVERAGENTS_FORCE_REPL=1` escape hatch exists but is completely undocumented in the `--help` output, making it undiscoverable. ## Current Behavior When `agents repl` is invoked without a TTY and without `CLEVERAGENTS_FORCE_REPL=1`: - **Exit code**: 0 (success — incorrect) - **Output**: Empty string (no output at all) - The REPL silently does nothing and exits cleanly **Root cause** — `src/cleveragents/cli/commands/repl.py`, lines 841–843: ```python def repl_callback(...) -> None: """Start an interactive REPL session.""" if sys.stdout.isatty() or os.environ.get("CLEVERAGENTS_FORCE_REPL"): raise SystemExit(run_repl(no_history=no_history, history_path=history_path)) # BUG: No else clause — silently exits with code 0 when condition is False ``` ## Expected Behavior When `agents repl` is invoked without a TTY and without `CLEVERAGENTS_FORCE_REPL=1`, the command should: 1. Print a helpful error message to stderr, e.g.: ``` Error: REPL requires an interactive terminal. Use CLEVERAGENTS_FORCE_REPL=1 to override. ``` 2. Exit with a non-zero exit code (e.g., 1) to signal failure ## Steps to Reproduce ```python from typer.testing import CliRunner from cleveragents.cli.main import app runner = CliRunner() # No TTY result = runner.invoke(app, ["repl"]) print(f"Exit code: {result.exit_code}") # 0 ← should be 1 print(f"Output: {repr(result.output)}") # '' ← should contain error message ``` Or from the command line: ```bash echo "" | agents repl # Piped input, no TTY # No output, exit code 0 ← incorrect ``` ## Suggested Fix Add an `else` clause to `repl_callback` in `src/cleveragents/cli/commands/repl.py`: ```python else: from rich.console import Console Console(stderr=True).print( "[red]Error:[/red] REPL requires an interactive terminal. " "Set [bold]CLEVERAGENTS_FORCE_REPL=1[/bold] to override." ) raise SystemExit(1) ``` Also update the `--help` docstring to mention the TTY requirement and the `CLEVERAGENTS_FORCE_REPL` environment variable. --- ## Subtasks - [ ] Add `else` clause to `repl_callback` in `src/cleveragents/cli/commands/repl.py` to print error to stderr and exit with code 1 when no TTY is available - [ ] Update `--help` docstring for `agents repl` to document the TTY requirement - [ ] Update `--help` docstring to document the `CLEVERAGENTS_FORCE_REPL=1` override - [ ] Tests (Behave): Add scenario for `agents repl` invoked without TTY — assert exit code 1 and error message on stderr - [ ] Tests (Behave): Add scenario for `agents repl` with `CLEVERAGENTS_FORCE_REPL=1` — assert REPL starts normally - [ ] 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. - 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: UAT Testing | Agent: ca-new-issue-creator
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.

Blocks
#397 Epic: Server & Autonomy Infrastructure
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#3972
No description provided.