fix(state): repair duplicate session titles without data loss on startup (#65602) - #65636
Closed
Tranquil-Flow wants to merge 1 commit into
Closed
fix(state): repair duplicate session titles without data loss on startup (#65602)#65636Tranquil-Flow wants to merge 1 commit into
Tranquil-Flow wants to merge 1 commit into
Conversation
teknium1
added a commit
that referenced
this pull request
Jul 16, 2026
… open Follow-up to the salvaged #65636: if the dedup UPDATE or the retried CREATE INDEX raises, log and continue — the unique title index is an optimization and must not block SessionDB initialization.
Contributor
|
Merged via PR #65689 — your commit was cherry-picked onto current main with your authorship preserved in git log (rebase-merge). We added one small follow-up on top wrapping the repair itself in a guard so index creation can never abort DB open. The no-data-loss UPDATE approach and the RED-proven tests were exactly right — thanks! |
3 tasks
Gravezzz
pushed a commit
to Gravezzz/hermes-agent
that referenced
this pull request
Jul 21, 2026
… open Follow-up to the salvaged NousResearch#65636: if the dedup UPDATE or the retried CREATE INDEX raises, log and continue — the unique title index is an optimization and must not block SessionDB initialization.
randlee
pushed a commit
to randlee/hermes-agent
that referenced
this pull request
Aug 11, 2026
… open Follow-up to the salvaged NousResearch#65636: if the dedup UPDATE or the retried CREATE INDEX raises, log and continue — the unique title index is an optimization and must not block SessionDB initialization.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SessionDB._init_schema()creates aUNIQUEpartial index onsessions.titlebut only catchessqlite3.OperationalError. Existing databases that contain duplicate non-null titles (from imports, context-compression continuations, or concurrent creation) raisesqlite3.IntegrityErrorinstead, which is uncaught — crashing Dashboard API calls that open the session database (/api/sessions/{id}/messages).Root cause
Commit
60b6abefd(session naming with unique titles) added theCREATE UNIQUE INDEXguarded only by anOperationalErrorhandler ("index already exists"). It does not handle the case where the index does not yet exist but the table already holds duplicate titles — which throwsIntegrityError.Fix
Catch
sqlite3.IntegrityErrorand repair the duplicates without deleting any data:newer.rowid > older.rowid) and settitle = NULLonly on the older conflicting aliases.OperationalError("index already exists") handler is preserved.Titles are optional aliases, so clearing an older alias does not lose the session or its messages.
Why not delete duplicate rows
The alternative (deleting duplicate sessions) causes severe transcript data loss. Competing PR #65628 uses:
That subquery only selects
MAX(rowid)within non-null-title groups, so every untitled session (the majority of normal sessions) is deleted, along with all but the newest duplicate. This fix preserves every row.Tests
New
TestSessionTitleIndexRepairclass intests/test_hermes_state.py(3 production-path tests against a real SQLite database):test_duplicate_titles_are_repaired_without_deleting_sessionstest_repaired_index_rejects_future_duplicate_titleset_session_titleis rejected (ValueError)test_clean_legacy_database_keeps_existing_titlesRED proof (on
upstream/mainbefore the production change): 2 of 3 tests fail withsqlite3.IntegrityError: UNIQUE constraint failed: sessions.titleat_init_schema; the clean-database test passes.GREEN after fix: focused class 3 passed; full
tests/test_hermes_state.py369 passed.ruff checkclean.Fixes #65602
Auto-published by Moonsong via Path B automated pipeline.