Skip to content

fix: preserve session_db on UNIQUE conflict and add /resume CLI command - #3183

Closed
Mibayy wants to merge 1 commit into
NousResearch:mainfrom
Mibayy:fix/session-resume-persistence
Closed

fix: preserve session_db on UNIQUE conflict and add /resume CLI command#3183
Mibayy wants to merge 1 commit into
NousResearch:mainfrom
Mibayy:fix/session-resume-persistence

Conversation

@Mibayy

@Mibayy Mibayy commented Mar 26, 2026

Copy link
Copy Markdown
Contributor

Fixes #3123 — two separate bugs in the --resume / /resume flow.

Bug 1: sessions not persisted (messages lost on --resume)

Root cause: The CLI creates the SQLite session row early in __init__. Then AIAgent.__init__ calls create_session() again for the same session ID, hits a UNIQUE constraint, and the exception handler sets self._session_db = None. From that point every append_message() call short-circuits — messages accumulate in memory only and are never written to the DB. On --resume, the session row exists but is empty ("found but has no messages").

Fix (run_agent.py): Distinguish UNIQUE/already-exists errors (expected when the caller pre-creates the session) from genuine failures. Only discard session_db for unexpected errors; silently skip for UNIQUE conflicts.

Bug 2: /resume unknown command in CLI

Root cause: _handle_resume_command exists only in gateway/run.py. The CLI slash-command dispatcher had no handler for resume, even though it's listed in commands.py without gateway_only=True.

Fix (cli.py): Add _handle_resume_command() to HermesCLI and wire it to canonical == "resume" in the dispatcher.

The new CLI handler supports:

  • /resume — lists recent named sessions
  • /resume <session-id> — switches to a session by its timestamp ID
  • /resume <title> — resolves by title (via resolve_session_by_title)

Flushes memories and ends the current session in the DB before switching, mirroring the gateway behaviour.

Two bugs fixed:

1. run_agent.py: AIAgent.__init__ called create_session() even when the
   CLI had already created the row. This triggered a UNIQUE constraint,
   the exception handler set self._session_db = None, and all subsequent
   append_message() calls were silent no-ops.  Messages accumulated in
   memory only — on --resume the session appeared empty.

   Fix: distinguish UNIQUE/already-exists errors (expected when the CLI
   pre-creates the session) from genuine failures.  Only null out
   session_db for unexpected errors.

2. cli.py: /resume was listed in commands.py but had no handler in the
   CLI slash-command dispatcher, causing 'Unknown command: /resume'.

   Fix: add _handle_resume_command() and wire it to canonical == 'resume'.
   Supports /resume with no args (lists named sessions), /resume <id>
   (direct session ID), and /resume <title> (title lookup via
   resolve_session_by_title).

Fixes NousResearch#3123
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for this diagnosis and the clear write-up, @Mibayy! Both bugs you identified have since been fixed on main via separate commits.

Bug 1 — session_db nulled on UNIQUE conflict (run_agent.py):
The current main takes an even broader approach: the create_session exception handler no longer nulls self._session_db at all. It logs a warning and keeps the DB reference alive in all error cases (run_agent.py, lines 1568–1577). This fully covers the UNIQUE-conflict scenario you diagnosed.

Bug 2 — /resume unknown command in CLI (cli.py):
_handle_resume_command() already exists at cli.py:4732 and is wired into the dispatcher at cli.py:6035. The current implementation is richer than this PR's version — it handles compression-chain following via resolve_resume_session_id, title lookup via _resolve_session_by_name_or_id, and reopen_session() to clear the ended_at timestamp. Prior commits f24956ba1, bd01ec788, and a456b50a3 document the history.

Closing as implemented on main. This is an automated hermes-sweeper review.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Session --resume not working

2 participants