Skip to content

Double memory flush on gateway restart when session expires #3059

@scottishclaymore

Description

@scottishclaymore

Bug Description

When a session expires and triggers a proactive memory flush, if the gateway restarts during or after the flush, the same session gets flushed again because the _pre_flushed_sessions set is in-memory only and resets on restart.

Evidence

From gateway logs at 2026-03-25 04:00-04:05:

04:00:18 - Session 20260324_075052_df00a65e expired, flushing memories proactively
[Hermes Gateway Starting...]  ← Gateway restarted
04:04:51 - Same session expired again, flushing memories proactively (duplicate!)

The session was flushed twice, causing:

  1. Duplicate LLM API calls via OpenRouter
  2. Memory tool errors as the LLM tried to save already-saved memories
  3. Wasted tokens and potential memory corruption

Root Cause

In gateway/session.py:

self._pre_flushed_sessions: set = set()  # session_ids already flushed by watcher

This set is initialized in __init__ and never persisted. When the gateway restarts, it resets to empty, so the expiry watcher in _session_expiry_watcher() sees the same expired session and flushes it again.

Proposed Fix

Persist _pre_flushed_sessions to state.db (the existing SQLite database used for other gateway state) so it survives restarts. The set should be:

  1. Written to state.db after each successful flush
  2. Loaded from state.db on gateway startup
  3. Cleaned up when sessions are actually reset/deleted

Additional Issue

The flush prompt should also account for memory being near/full. Currently it just says "save memories" without giving guidance to consolidate when at capacity. When memory is >90% full, the LLM generates invalid tool calls trying to work around the limit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions