UAT: agents session list --format json empty-case emits wrong structure — total at top-level instead of inside summary #6316

Closed
opened 2026-04-09 20:09:36 +00:00 by HAL9000 · 0 comments
Owner

Summary

When agents session list --format json is run with no sessions present, the command emits {"sessions": [], "total": 0}. This diverges from the spec-required structure in two ways: (1) total is emitted as a top-level key instead of nested inside a summary object, and (2) the summary object is absent entirely. Additionally, the outer command envelope is missing for this path (shared with the broader issue reported in #6269, but the empty-case uses a distinct early-return code path with a different wrong structure than the non-empty path).

Spec Reference

docs/specification.md §agents session list (around lines 1652–1687) shows the JSON output structure for all cases:

{
  "command": "agents --format table session list",
  "status": "ok",
  "exit_code": 0,
  "data": {
    "sessions": [],
    "summary": {
      "total": 0,
      "most_recent": null,
      "oldest": null,
      "total_messages": 0,
      "storage": "0 KB"
    }
  },
  "timing": { "duration_ms": 85 },
  "messages": [{ "level": "ok", "text": "0 sessions listed" }]
}

The summary object must always be present, with total, most_recent, oldest, total_messages, and storage keys. There is no top-level total key.

Code Location

File: src/cleveragents/cli/commands/session.py
Lines 291–299 — the empty-sessions early-return path:

if not sessions:
    # For machine-readable formats, always emit a structured empty list
    # so that callers parsing JSON/YAML receive valid output.
    if fmt not in (OutputFormat.RICH.value, OutputFormat.COLOR.value):
        typer.echo(format_output({"sessions": [], "total": 0}, fmt))
        return
    console.print("[yellow]No sessions found.[/yellow]")
    console.print("Create one with 'agents session create'")
    return

Issue: Line 295 passes {"sessions": [], "total": 0} directly to format_output. The total key is at top-level, and the summary sub-object is missing entirely.

Contrast with the non-empty path (lines 301–304), which uses _session_list_dict(sessions):

data = _session_list_dict(sessions)
if fmt not in (OutputFormat.RICH.value, OutputFormat.COLOR.value):
    typer.echo(format_output(data, fmt))

_session_list_dict (lines 125–162) correctly returns {"sessions": [...], "summary": {"total": N, ...}}. The empty-case path does NOT use _session_list_dict, causing the structural divergence.

Steps to Reproduce

# Ensure no sessions exist (or use a fresh database)
agents session list --format json

Expected Result

{
  "sessions": [],
  "summary": {
    "total": 0,
    "most_recent": null,
    "oldest": null,
    "total_messages": 0,
    "storage": "0 KB"
  }
}

(Plus the outer command envelope once #6269 is fixed.)

Actual Result

{"sessions": [], "total": 0}

Suggested Fix

Replace line 295 with a call to _session_list_dict([]), which already handles the empty case correctly (produces summary with total: 0, most_recent: null, oldest: null, total_messages: 0, storage: "0 KB"):

if fmt not in (OutputFormat.RICH.value, OutputFormat.COLOR.value):
    typer.echo(format_output(_session_list_dict([]), fmt))
    return

Additional Notes

  • This is a distinct bug from #6269 (missing outer envelope). Even after #6269 is fixed, this empty-case path would still emit the wrong data structure unless fixed separately.
  • _session_list_dict([]) already handles the empty case safely: sessions is [], total_messages is 0, and most_recent/oldest are None (lines 147–149).

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: uat-tester

## Summary When `agents session list --format json` is run with no sessions present, the command emits `{"sessions": [], "total": 0}`. This diverges from the spec-required structure in two ways: (1) `total` is emitted as a top-level key instead of nested inside a `summary` object, and (2) the `summary` object is absent entirely. Additionally, the outer command envelope is missing for this path (shared with the broader issue reported in #6269, but the empty-case uses a distinct early-return code path with a different wrong structure than the non-empty path). ## Spec Reference `docs/specification.md` §agents session list (around lines 1652–1687) shows the JSON output structure for all cases: ```json { "command": "agents --format table session list", "status": "ok", "exit_code": 0, "data": { "sessions": [], "summary": { "total": 0, "most_recent": null, "oldest": null, "total_messages": 0, "storage": "0 KB" } }, "timing": { "duration_ms": 85 }, "messages": [{ "level": "ok", "text": "0 sessions listed" }] } ``` The `summary` object must always be present, with `total`, `most_recent`, `oldest`, `total_messages`, and `storage` keys. There is no top-level `total` key. ## Code Location **File**: `src/cleveragents/cli/commands/session.py` **Lines 291–299** — the empty-sessions early-return path: ```python if not sessions: # For machine-readable formats, always emit a structured empty list # so that callers parsing JSON/YAML receive valid output. if fmt not in (OutputFormat.RICH.value, OutputFormat.COLOR.value): typer.echo(format_output({"sessions": [], "total": 0}, fmt)) return console.print("[yellow]No sessions found.[/yellow]") console.print("Create one with 'agents session create'") return ``` **Issue**: Line 295 passes `{"sessions": [], "total": 0}` directly to `format_output`. The `total` key is at top-level, and the `summary` sub-object is missing entirely. **Contrast with the non-empty path** (lines 301–304), which uses `_session_list_dict(sessions)`: ```python data = _session_list_dict(sessions) if fmt not in (OutputFormat.RICH.value, OutputFormat.COLOR.value): typer.echo(format_output(data, fmt)) ``` `_session_list_dict` (lines 125–162) correctly returns `{"sessions": [...], "summary": {"total": N, ...}}`. The empty-case path does NOT use `_session_list_dict`, causing the structural divergence. ## Steps to Reproduce ```bash # Ensure no sessions exist (or use a fresh database) agents session list --format json ``` ## Expected Result ```json { "sessions": [], "summary": { "total": 0, "most_recent": null, "oldest": null, "total_messages": 0, "storage": "0 KB" } } ``` (Plus the outer command envelope once #6269 is fixed.) ## Actual Result ```json {"sessions": [], "total": 0} ``` ## Suggested Fix Replace line 295 with a call to `_session_list_dict([])`, which already handles the empty case correctly (produces `summary` with `total: 0`, `most_recent: null`, `oldest: null`, `total_messages: 0`, `storage: "0 KB"`): ```python if fmt not in (OutputFormat.RICH.value, OutputFormat.COLOR.value): typer.echo(format_output(_session_list_dict([]), fmt)) return ``` ## Additional Notes - This is a distinct bug from #6269 (missing outer envelope). Even after #6269 is fixed, this empty-case path would still emit the wrong `data` structure unless fixed separately. - `_session_list_dict([])` already handles the empty case safely: `sessions` is `[]`, `total_messages` is `0`, and `most_recent`/`oldest` are `None` (lines 147–149). --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: uat-tester
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#6316
No description provided.