From a3d41fd5684366eb591d0d405354a0cb43a1de4f Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Thu, 26 Mar 2026 04:25:03 +0100 Subject: [PATCH] fix(federation): handle existing canonical_pair_id during backfill by merging duplicate first --- packages/server/src/db/migrate.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/server/src/db/migrate.ts b/packages/server/src/db/migrate.ts index 8554abc4..74515561 100644 --- a/packages/server/src/db/migrate.ts +++ b/packages/server/src/db/migrate.ts @@ -517,6 +517,16 @@ export function runMigrations(db: Database.Database): void { if (homeUserIds.length === 2) { const sorted = homeUserIds.sort(); const pairId = crypto.createHash('sha256').update(sorted.join(':')).digest('hex').slice(0, 32); + // Check if this pairId already exists on a relay-created channel + const existing = db.prepare('SELECT id FROM dm_channels WHERE canonical_pair_id = ?').get(pairId) as { id: string } | undefined; + if (existing) { + // A relay-created duplicate exists — merge it into this (older) channel, then set the pair ID + db.prepare('UPDATE dm_messages SET dm_channel_id = ? WHERE dm_channel_id = ?').run(channel.id, existing.id); + db.prepare('INSERT OR IGNORE INTO dm_members (dm_channel_id, user_id, closed) SELECT ?, user_id, closed FROM dm_members WHERE dm_channel_id = ?').run(channel.id, existing.id); + db.prepare('DELETE FROM dm_members WHERE dm_channel_id = ?').run(existing.id); + db.prepare('DELETE FROM dm_channels WHERE id = ?').run(existing.id); + console.log(`Federation: Merged relay-duplicate channel ${existing.id} into original ${channel.id}`); + } update.run(pairId, channel.id); backfilled++; }