BUG-HUNT: [error-handling] /session:export with --format md or --format txt calls service.get() without a None check — AttributeError crash when session does not exist in the service #6610

Open
opened 2026-04-09 22:16:03 +00:00 by HAL9000 · 0 comments
Owner

Bug Report: Error Handling — Unchecked None from service.get() in Session Export

Severity Assessment

  • Impact: Running /session export --format md or /session export --format txt when the current session ID has no corresponding record in the session service produces AttributeError: 'NoneType' object has no attribute 'messages', which propagates as "Export failed: 'NoneType' object has no attribute 'messages'" to the TUI. This is a confusing error and the md/txt export paths are permanently broken for new/fresh sessions.
  • Likelihood: Medium — any session that hasn't been explicitly created via the backend session service (e.g. the hardcoded "default" session ID in app.py) will trigger this.
  • Priority: High

Location

  • File: src/cleveragents/tui/commands.py
  • Function/Class: TuiCommandRouter._session_export
  • Lines: 149–183 (md branch lines 148–163, txt branch lines 164–184)

Description

_session_export() calls service.export_session(session_id) and then for md and txt formats additionally calls service.get(session_id) to obtain a Session object. service.get() can return None if the session doesn't exist, but the code proceeds to assign session.messages = messages without a None check:

# commands.py — md format branch
if fmt == "md":
    ...
    session = service.get(session_id)   # ← can return None
    messages = [
        SessionMessage(...)
        for m in export_data.get("messages", [])
    ]
    session.messages = messages   # ← AttributeError if session is None!
    content = session.as_export_markdown()
# commands.py — txt format branch
elif fmt == "txt":
    ...
    session = service.get(session_id)   # ← can return None
    messages = [...]
    session.messages = messages   # ← AttributeError if session is None!
    content = session.as_export_plain_text()

The outer except Exception as exc block converts this to "Export failed: 'NoneType' object has no attribute 'messages'", which is an unhelpful error message that doesn't tell the user what went wrong.

Note that export_data itself also comes from service.export_session(session_id) — if that also raises or returns empty data for a non-existent session, the entire export silently produces empty output.

Expected Behavior

Before accessing session.messages, the code should check whether session is None and return a descriptive error: "Session not found: {session_id}".

Actual Behavior

/session:export --format md (or txt) crashes with "Export failed: 'NoneType' object has no attribute 'messages'" for any session that service.get() cannot locate.

Suggested Fix

if fmt == "md":
    session = service.get(session_id)
    if session is None:
        return f"Session not found: {session_id}"
    messages = [SessionMessage(...) for m in export_data.get("messages", [])]
    session.messages = messages
    content = session.as_export_markdown()
elif fmt == "txt":
    session = service.get(session_id)
    if session is None:
        return f"Session not found: {session_id}"
    messages = [SessionMessage(...) for m in export_data.get("messages", [])]
    session.messages = messages
    content = session.as_export_plain_text()

Category

error-handling

TDD Note

After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. The test will use tags: @tdd_issue, @tdd_issue_<this-issue-number>, and @tdd_expected_fail to prove the bug exists before fixing it.


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

## Bug Report: Error Handling — Unchecked None from `service.get()` in Session Export ### Severity Assessment - **Impact**: Running `/session export --format md` or `/session export --format txt` when the current session ID has no corresponding record in the session service produces `AttributeError: 'NoneType' object has no attribute 'messages'`, which propagates as `"Export failed: 'NoneType' object has no attribute 'messages'"` to the TUI. This is a confusing error and the md/txt export paths are permanently broken for new/fresh sessions. - **Likelihood**: Medium — any session that hasn't been explicitly created via the backend session service (e.g. the hardcoded `"default"` session ID in `app.py`) will trigger this. - **Priority**: High ### Location - **File**: `src/cleveragents/tui/commands.py` - **Function/Class**: `TuiCommandRouter._session_export` - **Lines**: 149–183 (md branch lines 148–163, txt branch lines 164–184) ### Description `_session_export()` calls `service.export_session(session_id)` and then for `md` and `txt` formats additionally calls `service.get(session_id)` to obtain a `Session` object. `service.get()` can return `None` if the session doesn't exist, but the code proceeds to assign `session.messages = messages` without a None check: ```python # commands.py — md format branch if fmt == "md": ... session = service.get(session_id) # ← can return None messages = [ SessionMessage(...) for m in export_data.get("messages", []) ] session.messages = messages # ← AttributeError if session is None! content = session.as_export_markdown() ``` ```python # commands.py — txt format branch elif fmt == "txt": ... session = service.get(session_id) # ← can return None messages = [...] session.messages = messages # ← AttributeError if session is None! content = session.as_export_plain_text() ``` The outer `except Exception as exc` block converts this to `"Export failed: 'NoneType' object has no attribute 'messages'"`, which is an unhelpful error message that doesn't tell the user what went wrong. Note that `export_data` itself also comes from `service.export_session(session_id)` — if _that_ also raises or returns empty data for a non-existent session, the entire export silently produces empty output. ### Expected Behavior Before accessing `session.messages`, the code should check whether `session` is `None` and return a descriptive error: `"Session not found: {session_id}"`. ### Actual Behavior `/session:export --format md` (or `txt`) crashes with `"Export failed: 'NoneType' object has no attribute 'messages'"` for any session that `service.get()` cannot locate. ### Suggested Fix ```python if fmt == "md": session = service.get(session_id) if session is None: return f"Session not found: {session_id}" messages = [SessionMessage(...) for m in export_data.get("messages", [])] session.messages = messages content = session.as_export_markdown() elif fmt == "txt": session = service.get(session_id) if session is None: return f"Session not found: {session_id}" messages = [SessionMessage(...) for m in export_data.get("messages", [])] session.messages = messages content = session.as_export_plain_text() ``` ### Category error-handling ### TDD Note After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. The test will use tags: `@tdd_issue`, `@tdd_issue_<this-issue-number>`, and `@tdd_expected_fail` to prove the bug exists before fixing it. --- **Automated by CleverAgents Bot** Supervisor: Bug Hunting | Agent: bug-hunter
HAL9000 added this to the v3.2.0 milestone 2026-04-09 22:25:27 +00:00
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#6610
No description provided.