From b907b7eb85f97097e09dd1bdb2e38ed2feff51c0 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Mon, 31 Aug 2026 06:18:36 -0700 Subject: [PATCH] fix(buzz): compose #97502's membership-rejection matching into the per-subscription CLOSED handler - Widen the permanent-rejection match to the exact relay phrasings seen in production (#97502): 'not a channel member' and 'auth-required', alongside 'restricted'. - Close the re-adoption hole called out in review: _discover_dms() (both the dms-list path and the channels-list fallback) now skips channels in _restricted_channels, so a restricted channel dropped at runtime cannot be silently re-added by the next discovery sweep and re-trigger the rejection. - Credit: runtime CLOSED matching terms from PR #97502 by @repfigit; the per-subscription drop + restricted set is PR #76850 by @xozai. --- contributors/emails/joseleos@gmail.com | 1 + plugins/platforms/buzz/adapter.py | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 contributors/emails/joseleos@gmail.com diff --git a/contributors/emails/joseleos@gmail.com b/contributors/emails/joseleos@gmail.com new file mode 100644 index 0000000000..2c0a0c530b --- /dev/null +++ b/contributors/emails/joseleos@gmail.com @@ -0,0 +1 @@ +xozai diff --git a/plugins/platforms/buzz/adapter.py b/plugins/platforms/buzz/adapter.py index 8efa3b5116..17ef54ea06 100644 --- a/plugins/platforms/buzz/adapter.py +++ b/plugins/platforms/buzz/adapter.py @@ -1553,11 +1553,19 @@ class BuzzAdapter(BasePlatformAdapter): detail = message[-1] if len(message) > 2 else "subscription closed" sub_id = str(message[1]) if len(message) > 1 else "" closed_channel = subscriptions.get(sub_id) - # "restricted: …" means the relay will never - # serve this subscription — drop it permanently - # rather than reconnecting and repeating the - # same rejection in a tight loop. - if "restricted" in str(detail).lower() and closed_channel: + detail_l = str(detail).lower() + # A membership rejection ("restricted: not a + # channel member", bare "not a channel member", + # or "auth-required") means the relay will + # never serve this subscription — drop it + # permanently rather than reconnecting and + # repeating the same rejection in a tight loop. + is_membership_rejection = ( + "restricted" in detail_l + or "not a channel member" in detail_l + or "auth-required" in detail_l + ) + if is_membership_rejection and closed_channel: logger.warning( "Buzz: relay permanently rejected channel %s (%s) — " "removing from watch list", @@ -1759,7 +1767,7 @@ class BuzzAdapter(BasePlatformAdapter): if code == 0: for dm in _parse_json_list(out): dm_id = str(dm.get("dm_id") or "") - if not dm_id or dm_id in self._channel_state: + if not dm_id or dm_id in self._channel_state or dm_id in self._restricted_channels: continue if seed: await self._seed_channel(dm_id, chat_type="dm") @@ -1776,6 +1784,8 @@ class BuzzAdapter(BasePlatformAdapter): continue self._channel_meta[ch_id] = ch self._channel_names.setdefault(ch_id, str(ch.get("name") or ch_id)) + if ch_id in self._restricted_channels: + continue if not self._may_reclassify_as_dm(ch_id): continue if ch_id in self._channel_state: