From d28c8b0f4e9f8a8c54352d065ed9e632544bc7d8 Mon Sep 17 00:00:00 2001 From: kenny lopez Date: Tue, 25 Aug 2026 10:12:35 +0100 Subject: [PATCH] Propagate DM visibility snapshot-read errors instead of masking as convergence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The drift guard read the latest published snapshot with `.await.unwrap_or_default()`, turning a transient DB read *error* into an empty conveyed set. When canonical state was also empty (a resurface just cleared the hide), the guard mistook the fabricated empty for convergence and returned Ok(()) without republishing — leaving a stale snapshot that keeps the DM hidden on the client across reconnect/restart. Propagate the error with `?` so the per-recipient caller in resurface_dm_for_message_recipients records it and the message replay path retries. This matches the sibling `list_hidden_dms` read two lines above, which already uses `?`. Co-authored-by: Mongo <9cfd347903944d5b85aa6c93d2ab67381b978a92a31914bca69998968752a1d7@buzz.block.builderlab.xyz> Signed-off-by: kenny lopez --- crates/buzz-relay/src/handlers/side_effects.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/crates/buzz-relay/src/handlers/side_effects.rs b/crates/buzz-relay/src/handlers/side_effects.rs index 1cff9bdd4f..90de1091f6 100644 --- a/crates/buzz-relay/src/handlers/side_effects.rs +++ b/crates/buzz-relay/src/handlers/side_effects.rs @@ -3396,7 +3396,12 @@ pub async fn publish_dm_visibility_snapshot( let relay_pubkey_hex = state.relay_keypair.public_key().to_hex(); // Read the latest snapshot once: it feeds both the drift check below and the - // monotonic `created_at` bump. A missing snapshot conveys the empty set. + // monotonic `created_at` bump. A missing snapshot (empty `Ok`) conveys the + // empty set, but a read *error* must propagate: swallowing it as `[]` would + // let the drift guard below mistake a transient failure for convergence and + // report `Ok(())` while a stale snapshot survives, stranding a hidden DM on + // the client forever (Jude review: snapshot-read failure misreported as + // convergence). Propagating instead makes the caller log and retry. let existing = state .db .query_events(&buzz_db::event::EventQuery { @@ -3406,8 +3411,7 @@ pub async fn publish_dm_visibility_snapshot( limit: Some(1), ..buzz_db::event::EventQuery::for_community(tenant.community()) }) - .await - .unwrap_or_default(); + .await?; // Drift guard: skip the replace when the last published snapshot already // conveys the canonical hidden set. This makes republishing idempotent, so