BUG-HUNT: [output-format] console.print(format_output()) double-prints machine-readable output and adds blank line #7733

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

Bug Report: [Output Format] console.print(format_output()) Causes Double Output and Trailing Blank Line

Severity Assessment

  • Impact: Every command using --format json, --format yaml, or --format plain writes output to sys.stdout directly inside format_output(), then console.print("") is called with the empty string return value — producing an extra blank line at the end. Any script capturing JSON output will receive a trailing newline that can break strict JSON parsers expecting clean output.
  • Likelihood: Triggered on every invocation of any CLI command with a machine-readable format flag
  • Priority: High

Location

  • File: src/cleveragents/cli/formatting.py
  • Function: format_output
  • Lines: 305–315

And every call site, for example:

  • src/cleveragents/cli/commands/action.py:143,359,459
  • src/cleveragents/cli/commands/actor.py:436,870
  • src/cleveragents/cli/commands/plan.py:1122,2241,... (26+ sites)
  • src/cleveragents/cli/commands/automation_profile.py:130,302,409
  • src/cleveragents/cli/commands/invariant.py:137,220,272

Description

format_output() for machine-readable formats (json, yaml, plain) writes output directly to sys.stdout and returns an empty string "":

# formatting.py lines 308-315
if fmt in (OutputFormat.JSON.value, OutputFormat.YAML.value, OutputFormat.PLAIN.value):
    ...
    sys.stdout.write(rendered + "\n")
    sys.stdout.flush()
    return ""   # <-- empty string returned

All call sites then do:

console.print(format_output(data, fmt))  # prints the empty string -> adds a blank line

This means:

  1. The actual JSON/YAML output is written via sys.stdout.write()
  2. Then console.print("") prints an additional blank line via Rich (which goes to stdout)
  3. Output that should be clean JSON is polluted with an extra \n

Evidence

# src/cleveragents/cli/formatting.py
sys.stdout.write(rendered + "\n")
sys.stdout.flush()
return ""  # caller does console.print("") -> extra blank line

Affected call sites (sample):

# action.py:143
console.print(format_output(data, fmt))

# actor.py:436
console.print(format_output(data, fmt))

# plan.py:1122 (and 25+ more occurrences)
console.print(format_output(data, fmt))

Expected Behavior

When --format json is used, the output should be clean JSON with exactly one trailing newline. The call sites should use typer.echo(format_output(data, fmt)) or check the return value before printing.

Actual Behavior

Clean JSON output followed by one extra blank line from console.print(""). This can cause:

  • JSON parsers to fail if they read the trailing blank line as a second document
  • CI pipelines using $(agents plan list --format json) to capture malformed output
  • Scripting tools treating output as two lines

Suggested Fix

Either:

  1. Have call sites use typer.echo(format_output(data, fmt)) which handles the empty return cleanly (typer.echo skips empty strings with nl=True), OR
  2. Have format_output() return None for machine-readable formats (not an empty string) and guard against None in call sites, OR
  3. Change call sites from console.print(format_output(...)) to just format_output(...) (rely on the internal sys.stdout.write), which is the correct usage.

The session.py and config.py modules already do it correctly using typer.echo(format_output(...)). The pattern should be standardised across all 26+ call sites.

Category

output-format

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: [Output Format] `console.print(format_output())` Causes Double Output and Trailing Blank Line ### Severity Assessment - **Impact**: Every command using `--format json`, `--format yaml`, or `--format plain` writes output to `sys.stdout` directly inside `format_output()`, then `console.print("")` is called with the empty string return value — producing an extra blank line at the end. Any script capturing JSON output will receive a trailing newline that can break strict JSON parsers expecting clean output. - **Likelihood**: Triggered on every invocation of any CLI command with a machine-readable format flag - **Priority**: High ### Location - **File**: `src/cleveragents/cli/formatting.py` - **Function**: `format_output` - **Lines**: 305–315 And every call site, for example: - `src/cleveragents/cli/commands/action.py:143,359,459` - `src/cleveragents/cli/commands/actor.py:436,870` - `src/cleveragents/cli/commands/plan.py:1122,2241,...` (26+ sites) - `src/cleveragents/cli/commands/automation_profile.py:130,302,409` - `src/cleveragents/cli/commands/invariant.py:137,220,272` ### Description `format_output()` for machine-readable formats (`json`, `yaml`, `plain`) writes output directly to `sys.stdout` and returns an empty string `""`: ```python # formatting.py lines 308-315 if fmt in (OutputFormat.JSON.value, OutputFormat.YAML.value, OutputFormat.PLAIN.value): ... sys.stdout.write(rendered + "\n") sys.stdout.flush() return "" # <-- empty string returned ``` All call sites then do: ```python console.print(format_output(data, fmt)) # prints the empty string -> adds a blank line ``` This means: 1. The actual JSON/YAML output is written via `sys.stdout.write()` 2. Then `console.print("")` prints an additional blank line via Rich (which goes to stdout) 3. Output that should be clean JSON is polluted with an extra `\n` ### Evidence ```python # src/cleveragents/cli/formatting.py sys.stdout.write(rendered + "\n") sys.stdout.flush() return "" # caller does console.print("") -> extra blank line ``` Affected call sites (sample): ```python # action.py:143 console.print(format_output(data, fmt)) # actor.py:436 console.print(format_output(data, fmt)) # plan.py:1122 (and 25+ more occurrences) console.print(format_output(data, fmt)) ``` ### Expected Behavior When `--format json` is used, the output should be clean JSON with exactly one trailing newline. The call sites should use `typer.echo(format_output(data, fmt))` or check the return value before printing. ### Actual Behavior Clean JSON output followed by one extra blank line from `console.print("")`. This can cause: - JSON parsers to fail if they read the trailing blank line as a second document - CI pipelines using `$(agents plan list --format json)` to capture malformed output - Scripting tools treating output as two lines ### Suggested Fix Either: 1. Have call sites use `typer.echo(format_output(data, fmt))` which handles the empty return cleanly (typer.echo skips empty strings with `nl=True`), OR 2. Have `format_output()` return `None` for machine-readable formats (not an empty string) and guard against `None` in call sites, OR 3. Change call sites from `console.print(format_output(...))` to just `format_output(...)` (rely on the internal `sys.stdout.write`), which is the correct usage. The `session.py` and `config.py` modules already do it correctly using `typer.echo(format_output(...))`. The pattern should be standardised across all 26+ call sites. ### Category output-format ### 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:46:20 +00:00
Author
Owner

Verified — Output format bug: double-printing machine-readable output with blank line. MoSCoW: Should-have. Priority: Medium.


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

✅ **Verified** — Output format bug: double-printing machine-readable output with blank line. MoSCoW: Should-have. Priority: Medium. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Author
Owner

Verified — Output format bug: double-printing machine-readable output with blank line. MoSCoW: Should-have. Priority: Medium.


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

✅ **Verified** — Output format bug: double-printing machine-readable output with blank line. MoSCoW: Should-have. Priority: Medium. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Author
Owner

Verified — Output format bug: double-printing machine-readable output with blank line. MoSCoW: Should-have. Priority: Medium.


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

✅ **Verified** — Output format bug: double-printing machine-readable output with blank line. MoSCoW: Should-have. Priority: Medium. --- **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#7733
No description provided.