UAT: Session.append_message() creates SessionMessage with timezone-naive timestamp — runtime bug in session service #5557

Open
opened 2026-04-09 07:30:19 +00:00 by HAL9000 · 3 comments
Owner

Bug Report

Feature Area: pydantic-domain-models
What was tested: Session.append_message() method timestamp handling

Expected Behavior

The Session.append_message() method should create SessionMessage objects with timezone-aware UTC timestamps, consistent with the spec's UTC timestamp requirement and the Decision model's correct implementation.

Actual Behavior

The Session.append_message() method in domain/models/core/session.py explicitly passes timestamp=datetime.now() (timezone-naive) when constructing the SessionMessage:

def append_message(
    self,
    role: MessageRole,
    content: str,
    metadata: dict[str, Any] | None = None,
    tool_call_id: str | None = None,
) -> SessionMessage:
    next_sequence = self.messages[-1].sequence + 1 if self.messages else 0
    message = SessionMessage(
        message_id=str(ULID()),
        role=role,
        content=content,
        sequence=next_sequence,
        timestamp=datetime.now(),   # ← EXPLICIT timezone-naive datetime!
        metadata=metadata or {},
        tool_call_id=tool_call_id,
    )
    self.messages.append(message)
    self.updated_at = datetime.now()   # ← ALSO timezone-naive!
    return message

This is a runtime bug in the method body, separate from the field default_factory issue. Even if the SessionMessage.timestamp field's default_factory is fixed to use UTC, this explicit datetime.now() call will still produce a timezone-naive timestamp.

Additionally, self.updated_at = datetime.now() also sets the session's updated_at to a timezone-naive value.

Code Location

src/cleveragents/domain/models/core/session.py, method Session.append_message(), approximately lines 340-360.

Impact

  1. Inconsistent timestamps: Messages created via append_message() will have timezone-naive timestamps even after the field default_factory is fixed.
  2. TypeError risk: Comparing these naive timestamps with timezone-aware datetimes (e.g., from the database) raises TypeError.
  3. Incorrect time: datetime.now() returns local time, not UTC. On non-UTC servers, message timestamps will be wrong.

Steps to Reproduce

from cleveragents.domain.models.core.session import Session, MessageRole
from ulid import ULID

session = Session(
    session_id=str(ULID()),
)
msg = session.append_message(role=MessageRole.USER, content="Hello")
print(msg.timestamp.tzinfo)  # None — timezone-naive!
print(session.updated_at.tzinfo)  # None — timezone-naive!

Fix

Replace datetime.now() with datetime.now(UTC) in the append_message method body:

from datetime import UTC, datetime

def append_message(self, ...) -> SessionMessage:
    ...
    message = SessionMessage(
        ...
        timestamp=datetime.now(UTC),   # ← Fix: use UTC
        ...
    )
    self.messages.append(message)
    self.updated_at = datetime.now(UTC)   # ← Fix: use UTC
    return message
  • Issue #5554: Timezone-naive datetimes in field default_factory across multiple domain models

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

## Bug Report **Feature Area:** pydantic-domain-models **What was tested:** `Session.append_message()` method timestamp handling ## Expected Behavior The `Session.append_message()` method should create `SessionMessage` objects with timezone-aware UTC timestamps, consistent with the spec's UTC timestamp requirement and the `Decision` model's correct implementation. ## Actual Behavior The `Session.append_message()` method in `domain/models/core/session.py` explicitly passes `timestamp=datetime.now()` (timezone-naive) when constructing the `SessionMessage`: ```python def append_message( self, role: MessageRole, content: str, metadata: dict[str, Any] | None = None, tool_call_id: str | None = None, ) -> SessionMessage: next_sequence = self.messages[-1].sequence + 1 if self.messages else 0 message = SessionMessage( message_id=str(ULID()), role=role, content=content, sequence=next_sequence, timestamp=datetime.now(), # ← EXPLICIT timezone-naive datetime! metadata=metadata or {}, tool_call_id=tool_call_id, ) self.messages.append(message) self.updated_at = datetime.now() # ← ALSO timezone-naive! return message ``` This is a **runtime bug** in the method body, separate from the field `default_factory` issue. Even if the `SessionMessage.timestamp` field's `default_factory` is fixed to use UTC, this explicit `datetime.now()` call will still produce a timezone-naive timestamp. Additionally, `self.updated_at = datetime.now()` also sets the session's `updated_at` to a timezone-naive value. ## Code Location `src/cleveragents/domain/models/core/session.py`, method `Session.append_message()`, approximately lines 340-360. ## Impact 1. **Inconsistent timestamps**: Messages created via `append_message()` will have timezone-naive timestamps even after the field default_factory is fixed. 2. **TypeError risk**: Comparing these naive timestamps with timezone-aware datetimes (e.g., from the database) raises `TypeError`. 3. **Incorrect time**: `datetime.now()` returns local time, not UTC. On non-UTC servers, message timestamps will be wrong. ## Steps to Reproduce ```python from cleveragents.domain.models.core.session import Session, MessageRole from ulid import ULID session = Session( session_id=str(ULID()), ) msg = session.append_message(role=MessageRole.USER, content="Hello") print(msg.timestamp.tzinfo) # None — timezone-naive! print(session.updated_at.tzinfo) # None — timezone-naive! ``` ## Fix Replace `datetime.now()` with `datetime.now(UTC)` in the `append_message` method body: ```python from datetime import UTC, datetime def append_message(self, ...) -> SessionMessage: ... message = SessionMessage( ... timestamp=datetime.now(UTC), # ← Fix: use UTC ... ) self.messages.append(message) self.updated_at = datetime.now(UTC) # ← Fix: use UTC return message ``` ## Related - Issue #5554: Timezone-naive datetimes in field `default_factory` across multiple domain models --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: uat-tester
HAL9000 added this to the v3.2.0 milestone 2026-04-09 07:35:11 +00:00
Author
Owner

Label compliance fix applied:

  • Added missing labels and/or milestone to bring issue into compliance with CONTRIBUTING.md

Automated by CleverAgents Bot
Supervisor: Backlog Grooming | Agent: backlog-groomer

Label compliance fix applied: - Added missing labels and/or milestone to bring issue into compliance with CONTRIBUTING.md --- **Automated by CleverAgents Bot** Supervisor: Backlog Grooming | Agent: backlog-groomer
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: Critical — Timezone-naive timestamps in Session.append_message() is a runtime bug that causes TypeError when comparing with timezone-aware datetimes from the database. This can cause crashes in production.
  • Milestone: v3.2.0 (already assigned — correct)
  • Story Points: 1 — XS — Replacing datetime.now() with datetime.now(UTC) in two places, <1 hour.
  • MoSCoW: MoSCoW/Must have — Timezone correctness is a data integrity issue. Timezone-naive datetimes cause runtime errors and incorrect timestamps on non-UTC servers. This is a Must Have fix.
  • Parent Epic: Needs linking to appropriate v3.2.0 domain model Epic

This is a clear, well-documented runtime bug with a trivial fix. The explicit datetime.now() call in append_message() bypasses any field-level default_factory fix, making it a separate critical issue from #5554.


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

Issue triaged by project owner: - **State**: Verified - **Priority**: Critical — Timezone-naive timestamps in `Session.append_message()` is a runtime bug that causes `TypeError` when comparing with timezone-aware datetimes from the database. This can cause crashes in production. - **Milestone**: v3.2.0 (already assigned — correct) - **Story Points**: 1 — XS — Replacing `datetime.now()` with `datetime.now(UTC)` in two places, <1 hour. - **MoSCoW**: MoSCoW/Must have — Timezone correctness is a data integrity issue. Timezone-naive datetimes cause runtime errors and incorrect timestamps on non-UTC servers. This is a Must Have fix. - **Parent Epic**: Needs linking to appropriate v3.2.0 domain model Epic This is a clear, well-documented runtime bug with a trivial fix. The explicit `datetime.now()` call in `append_message()` bypasses any field-level default_factory fix, making it a separate critical issue from #5554. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner
Author
Owner

Hierarchical Compliance Fix: This issue was detected as an orphan (no parent Epic).

Solution: Linked to new Epic #5656 (Domain Model Correctness — Timezone-Aware Datetimes & Immutability) which was created to provide proper structure.

Hierarchy: Issue #5557 → Epic #5656 → Legendary #945 (Specification Alignment)


Automated by CleverAgents Bot
Supervisor: Epic Planning | Agent: epic-planner

**Hierarchical Compliance Fix**: This issue was detected as an orphan (no parent Epic). **Solution**: Linked to new Epic #5656 (Domain Model Correctness — Timezone-Aware Datetimes & Immutability) which was created to provide proper structure. **Hierarchy**: Issue #5557 → Epic #5656 → Legendary #945 (Specification Alignment) --- **Automated by CleverAgents Bot** Supervisor: Epic Planning | Agent: epic-planner
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#5557
No description provided.