From 07e8717750401ae62038e753075e96d356cbab94 Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Tue, 16 Jun 2026 16:36:45 +0100 Subject: [PATCH] PLAT-36990: recover never-bridged messages in forward backfill Messenger messages that arrived while the bridge was offline could be permanently lost: a reconnect snapshot advanced the sync cursor past skipped threads, and forward backfill then dropped those never-bridged mid-timeline messages purely because their timestamp was older than the portal anchor. Remove the forward timestamp trim and set AggressiveDeduplication on forward responses so bridgev2 deduplicates by message ID, dropping already-bridged messages while retaining never-bridged ones. Keep the backward timestamp trim unchanged. --- pkg/connector/backfill.go | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/pkg/connector/backfill.go b/pkg/connector/backfill.go index 6a6a4255..9744dca2 100644 --- a/pkg/connector/backfill.go +++ b/pkg/connector/backfill.go @@ -318,16 +318,10 @@ func (m *MetaClient) wrapBackfillEvents(ctx context.Context, portal *bridgev2.Po } return false }) - if anchor != nil { - if forward { - upsert.Messages = slices.DeleteFunc(upsert.Messages, func(message *table.WrappedMessage) bool { - return message.TimestampMs <= anchor.Timestamp.UnixMilli() - }) - } else { - upsert.Messages = slices.DeleteFunc(upsert.Messages, func(message *table.WrappedMessage) bool { - return message.TimestampMs >= anchor.Timestamp.UnixMilli() - }) - } + if anchor != nil && !forward { + upsert.Messages = slices.DeleteFunc(upsert.Messages, func(message *table.WrappedMessage) bool { + return message.TimestampMs >= anchor.Timestamp.UnixMilli() + }) } wrappedMessages := make([]*bridgev2.BackfillMessage, len(upsert.Messages)) for i, msg := range upsert.Messages { @@ -371,5 +365,9 @@ func (m *MetaClient) wrapBackfillEvents(ctx context.Context, portal *bridgev2.Po Messages: wrappedMessages, HasMore: upsert.Range.HasMoreBefore, MarkRead: upsert.MarkRead, + // Forward backfill can fetch a range covering never-bridged mid-timeline messages (older than + // the anchor) that a reconnect snapshot skipped. Deduplicate by message ID instead of trimming + // on timestamp so those messages are recovered while genuine duplicates are still dropped. + AggressiveDeduplication: forward, } }