hermes - 💡(How to fix) Fix [Bug]: Orphaned sessions never committed to OpenViking when new Hermes CLI process takes over

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

When a new Hermes CLI process starts while a previous CLI process's session is still active (or was killed without cleanup), the old session's OpenViking commit is never sent. The session's messages were synced to OpenViking via sync_turn() during live conversation, but the final POST /api/v1/sessions/{sid}/commit that triggers memory extraction never fires.

This affects two specific scenarios:

Scenario A — Process takeover without cleanup: User starts a second hermes command in a new terminal while the first is still running. The first session gets ended_at=NULL in state.db. The first process is eventually killed (SIGKILL, terminal close, SIGHUP). _run_cleanup() never runs. OpenViking commit never fires.

Scenario B — /new rotation then crash: User rotates via /new in the CLI. new_session() calls end_session(old_sid, "new_session") and commit_memory_session() on the agent, but if the process crashes before the OpenViking HTTP response returns (timeout, SIGKILL, etc.), the session remains committed in state.db but uncommitted in OpenViking.

Error Message

  • Silent data loss: No error is logged. The session simply never appears in OpenViking's committed session list.

Root Cause

The Hermes CLI has no startup mechanism to discover and finalize orphaned sessions. _run_state_db_auto_maintenance() runs in __init__ but only handles pruning/vacuum — not OpenViking commits.

The per-process cleanup chain (Ctrl+C/Ctrl+D → _run_cleanup()shutdown_memory_provider()on_session_end() → POST /commit) works correctly for clean exits, but there is no cross-process safety net.

Fix Action

Fix / Workaround

The function described above could be merged into _run_state_db_auto_maintenance() in cli.py, or be integrated into the Hermes CLI's startup lifecycle as a plugin hook (on_startup event).

RAW_BUFFERClick to expand / collapse

[Bug]: Orphaned sessions never committed to OpenViking when new Hermes CLI process takes over

Description

When a new Hermes CLI process starts while a previous CLI process's session is still active (or was killed without cleanup), the old session's OpenViking commit is never sent. The session's messages were synced to OpenViking via sync_turn() during live conversation, but the final POST /api/v1/sessions/{sid}/commit that triggers memory extraction never fires.

This affects two specific scenarios:

Scenario A — Process takeover without cleanup: User starts a second hermes command in a new terminal while the first is still running. The first session gets ended_at=NULL in state.db. The first process is eventually killed (SIGKILL, terminal close, SIGHUP). _run_cleanup() never runs. OpenViking commit never fires.

Scenario B — /new rotation then crash: User rotates via /new in the CLI. new_session() calls end_session(old_sid, "new_session") and commit_memory_session() on the agent, but if the process crashes before the OpenViking HTTP response returns (timeout, SIGKILL, etc.), the session remains committed in state.db but uncommitted in OpenViking.

Root Cause

The Hermes CLI has no startup mechanism to discover and finalize orphaned sessions. _run_state_db_auto_maintenance() runs in __init__ but only handles pruning/vacuum — not OpenViking commits.

The per-process cleanup chain (Ctrl+C/Ctrl+D → _run_cleanup()shutdown_memory_provider()on_session_end() → POST /commit) works correctly for clean exits, but there is no cross-process safety net.

Impact

  • Lost memory extraction: Sessions exist in OpenViking with their full message history but are never "finalized" — the automatic 6-category memory extraction (profile, preferences, entities, events, cases, patterns) never runs.
  • Silent data loss: No error is logged. The session simply never appears in OpenViking's committed session list.
  • Accumulation of "active" sessions in state.db: Hundreds of sessions with ended_at=NULL accumulate in state.db, polluting the session database with ghost entries.

Evidence

Before the fix, 382 CLI sessions in state.db had ended_at IS NULL but started_at > 60s ago — these were sessions from dead processes. 4 of these had messages in OpenViking that were never committed.

Local Fix Applied

Added _commit_orphaned_openviking_sessions() to cli.py, called during __init__ right after _run_state_db_auto_maintenance(). The function:

  1. Checks OpenViking health endpoint — silent skip if unavailable
  2. Queries state.db for orphan candidates:
    • ended_at IS NULL AND started_at < now - 60s AND message_count > 0 (abandoned active sessions)
    • end_reason = 'new_session' AND ended_at > now - 120s AND message_count > 0 (recently rotated, possibly uncommitted)
  3. For each candidate, sends POST /api/v1/sessions/{sid}/commit to OpenViking (idempotent — duplicate commits return OK)
  4. Closes abandoned CLI sessions in state.db with end_reason='orphaned_restart' to prevent re-processing
  5. Never raises — orphan recovery must never block interactive startup

Files changed:

  • cli.py — new function + call in __init__

Proposed Upstream Fix

The function described above could be merged into _run_state_db_auto_maintenance() in cli.py, or be integrated into the Hermes CLI's startup lifecycle as a plugin hook (on_startup event).

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING