diff --git a/backend/app/core/database.py b/backend/app/core/database.py index 13600ff64..5cc855907 100644 --- a/backend/app/core/database.py +++ b/backend/app/core/database.py @@ -1530,6 +1530,17 @@ async def run_migrations(conn): "CREATE INDEX IF NOT EXISTS ix_library_files_deleted_at ON library_files(deleted_at)", ) + # Legacy SQLite installs created `settings` without a UNIQUE constraint on `key`, + # so `INSERT OR IGNORE` below silently degrades to a plain INSERT and dupes rows on + # every restart. Dedupe (keep lowest id per key) and add the missing unique index + # before seeding. Safe/idempotent on both dialects — fresh installs already have + # no dupes and `create_all` already emits the index. + await _safe_execute( + conn, + "DELETE FROM settings WHERE id NOT IN (SELECT MIN(id) FROM settings GROUP BY key)", + ) + await _safe_execute(conn, "CREATE UNIQUE INDEX IF NOT EXISTS ix_settings_key ON settings(key)") + # Seed default settings keys that must exist on fresh install default_settings = [ ("advanced_auth_enabled", "false"),