Skip to content

AUDIT-10 — Medium-High — Session-history load failure is silent and destructive #67

Closed

Description

@getdownandcode

Summary

Severity: Medium-High
Area: Sessions
Affected files: agentkit/core/agent.py:176-180, agentkit/memory/redis_store.py:61-70
Suggested branch: fix/session-history-load-failure
Suggested PR title: fix(agent): stop silently discarding session history

This is finding AUDIT-10 of 18 from a consolidated audit of agentkit/. It is deliberately self-contained so it can be fixed on its own branch with its own PR.

Related findings: Related: AUDIT-04, AUDIT-11.


AUDIT-10 — Medium-High — Session-history load failure is silent and destructive

File — agentkit/core/agent.py:176-180

            messages: list[Message] = []
            if session_id and self.memory is not None and hasattr(self.memory, "get_messages"):
                with contextlib.suppress(Exception):
                    loaded = await self.memory.get_messages(session_id)
                    if loaded:
                        messages = list(loaded)

Why this is a bug

If the session history cannot be read (Redis down, corrupt JSON, a Message that fails validation — note RedisMemoryStore.get_messages returns [] on any deserialisation error, redis_store.py:61-70), the agent silently behaves as if it were a brand-new conversation. The subsequent save_messages then overwrites the existing history with the truncated new one. The result: multi-turn context is permanently lost, with no log line and no error in the response.

Pass cases

  • A failure to load session history is logged at ERROR/WARNING with the session_id.
  • A load failure does not silently replace the stored history: either the run fails explicitly, or the existing history is preserved (no destructive overwrite).
  • A corrupt/unreadable history entry (e.g. invalid Message payload) is surfaced rather than reduced to an empty list.
  • Regression test: force get_messages to raise, assert (a) a log record exists, (b) the previously stored messages are still present afterwards.


Definition of done (per AGENTS.md)

  • New/updated unit and integration tests covering the pass cases above, all passing (pytest).
  • ruff check ., ruff format --check . and mypy agentkit clean.
  • Docstrings updated where behaviour changed; docs/PROGRESS.md updated (status, PR link, commit count, notes).
  • A new ADR in docs/DECISIONS.md if an architectural decision was made.
  • Branch pushed and PR opened (never commit directly to main).

Baseline at the time of writing: pytest is green on main (all tests pass; tests/real/* skipped unless AGENTKIT_REAL_INFRA=1).

Activity

  1. getdownandcode commented on Oct 20, 2026

    @getdownandcode
    OwnerAuthor

    Audit index (18 separate issues, fix one by one)

    ID Issue Severity
    AUDIT-01 #58 Critical
    AUDIT-02 #59 Critical
    AUDIT-03 #60 High
    AUDIT-04 #61 High
    AUDIT-05 #62 High
    AUDIT-06 #63 High/Medium
    AUDIT-07 #64 Medium-High
    AUDIT-08 #65 Medium-High
    AUDIT-09 #66 Medium-High
    AUDIT-10 #67 Medium-High
    AUDIT-11 #68 Medium
    AUDIT-12 #69 Medium
    AUDIT-13 #70 Medium
    AUDIT-14 #71 Medium
    AUDIT-15 #72 Medium
    AUDIT-16 #73 Medium
    AUDIT-17 #74 Low
    AUDIT-18 #75 Low/Deployment

    Each issue is self-contained: current code, reproduction, pass cases, suggested branch and PR title. Reference the relevant one with Fixes #NN in your PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions