Skip to content

Desktop reconnect replay re-alerts old thread replies and plays false notification sound #3215

Open

Description

@billerickson

Describe the bug

Buzz Desktop plays the configured thread-reply notification sound after a
relay reconnect even when no new message has arrived. The visible timeline
does not show a duplicate, but an already-delivered thread reply appears to
pass through the desktop-notification callback again during reconnect replay.

The relay connection card itself is silent; the sound coincides with
Reconnecting → Connected because live channel subscriptions are replayed
at that point.

Steps to reproduce

  1. In Buzz Desktop, enable desktop notifications and the Thread replies
    alert row under Settings → Notifications.
  2. Receive a reply in a thread the current user authored, participated in, or
    follows.
  3. Leave Buzz open without receiving any newer messages.
  4. Interrupt the relay connection, or reproduce while the relay/load balancer
    is temporarily unavailable, and allow Buzz to reconnect.
  5. Observe that Buzz plays the configured notification sound after reconnect,
    despite there being no new visible message.
  6. Repeat the disconnect/reconnect. The same chirp can occur on every cycle.

Turning off only the Thread replies alert row suppresses the false chirp
while leaving the other alert classes enabled.

Expected behavior

Reconnect replay may redeliver an event to restore client state, but an event
ID that has already passed through the desktop-notification path must not
create another notification or play another sound.

Version and platform

  • Buzz version: 0.4.26 (xyz.block.buzz.app)
  • OS: macOS 15.1 (24B2082), Apple Silicon

Logs / additional context

This was observed during a relay incident in which other clients reported
503 Service Unavailable. A separate authenticated WebSocket probe connected
to the same relay recorded:

  • 2026-07-27T21:19:20.826Z: abnormal close 1006, empty reason,
    wasClean: false
  • 2026-07-27T21:19:26.652Z: reconnect opened; authentication accepted at
    21:19:26.957Z
  • 2026-07-27T21:19:29Z: Buzz Desktop visibly reconnected and chirped
  • 2026-07-27T21:19:42.490Z: probe closed with 1006 again

The transport outage is only the trigger for this report. The client bug is
that reconnecting re-alerts an already-delivered event.

Source-level findings in the v0.4.26 release:

  1. desktop/src/features/sidebar/ui/SidebarRelayConnectionCard.tsx and
    useSidebarRelayConnectionCard.ts contain no sound call.
  2. desktop/src/shared/api/relayReconnectReplay.ts replays each live
    subscription from five seconds before lastSeenCreatedAt.
  3. That watermark is the latest event timestamp, not wall-clock time, so it
    remains fixed during a quiet period and the same latest event can be
    returned on every reconnect.
  4. prepareSubscriptionEvent() in
    desktop/src/shared/api/relayClosedRecovery.ts advances the timestamp but
    does not deduplicate by event ID.
  5. desktop/src/features/channels/useLiveChannelUpdates.ts has bounded
    event-ID gates for DM and mention paths, but the qualifying thread-reply
    path can call onThreadReplyDesktopNotification without an equivalent
    gate.
  6. desktop/src/app/useAppShellDesktopNotifications.ts plays the configured
    thread_reply sound whenever that callback successfully sends the desktop
    notification.

This establishes a source path that matches the one-chirp-per-reconnect
behavior. The exact replayed event ID is not available because the release
build does not log notification attempts or the event ID passed to the sound
call.

Suggested fix:

  • Add bounded event-ID deduplication before invoking thread-reply desktop
    notifications, retaining the set across reconnect replay.
  • Add a regression test that delivers a thread reply, reconnects with the same
    event in the replay window, and asserts that the notification/sound callback
    runs exactly once.
  • Consider adding a reconnect watermark for live subscriptions that have no
    lastSeenCreatedAt, rather than resending the original subscription window.

Activity

  1. mastercoderkem commented on Jul 28, 2026

    @mastercoderkem

    Corroborating report from a different environment, with a more severe symptom than the sound-only case in the original description.

    Symptom: visible banners, not just a chirp. On this machine the reconnect replay produces full desktop notification banners that accumulate in macOS Notification Center. Notification Center currently holds dozens of copies of the same two thread replies, each stamped with a fresh delivery time. The underlying messages are ~25 hours old.

    Environment

    • Buzz Desktop 0.4.26 (xyz.block.buzz.app)
    • macOS 26.5.2 (25F84), Apple M4 Max
    • Hosted relay on *.communities.buzz.xyz
    • Desktop process uptime at time of capture: 1 day, 0:54 — never quit or relaunched since the two messages arrived

    Note the macOS version differs substantially from the original report (15.1), so this is not OS-version-specific.

    What was verified

    I queried the channel directly from the relay via buzz-cli. The channel holds 15 events total, each existing exactly once — no duplicate events server-side. The two events being re-alerted are single copies:

    event (prefix) created_at (UTC)
    0cc5bbbb52 2026-07-27 16:39:39
    a6c9d2f6e8 2026-07-27 16:44:20

    Both are thread replies (NIP-10 e tag, reply marker) to a root the notified user participated in — the qualifying path described in the original report. The notification header reads Reply in #<channel>, confirming the thread_reply alert class.

    Two details that may refine the model in the description

    1. Both events replay together on every cycle, not just the latest one. Notification Center shows them arriving as pairs at 2m, 4m, 7m, 9m, and 16m ago. The two events are 4m41s apart, which is well outside the "five seconds before lastSeenCreatedAt" replay window in relayReconnectReplay.ts. That window would predict only a6c9d2f6e8 replaying. Both replaying is more consistent with the subscription having no lastSeenCreatedAt and the original subscription filter being resent — which is exactly the third item in your suggested fix. That suggestion may be load-bearing rather than optional.

    2. It persists indefinitely during a quiet period. No newer message arrived in this channel for ~25 hours, so the watermark stayed frozen and every reconnect re-alerted the same pair. Observed cadence is roughly one cycle every 2–7 minutes, which implies frequent reconnects. Hosted relay on communities.buzz.xyz unreachable — Cloudflare 521, all relay HTTP endpoints time out #3247 documents hosted-relay instability (Cloudflare 521) in the same window and plausibly supplies that reconnect trigger.

    The practical impact of the frozen watermark is that the quieter a channel is, the worse this gets: the same alert repeats until someone posts something newer.

    Not verified. I could not read the macOS notification database (no Full Disk Access from this shell), and the release build writes no log I could locate under ~/Library/Application Support/Buzz/ or ~/Library/Logs/, so I have no client-side record of the notification attempts or the event IDs passed to the notification callback. The event identification above comes from matching notification body text to relay events, not from client logs.

    Happy to capture anything more specific from this machine if it would help — it is currently reproducing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions