From 442888a05b6b3bc1ae52b944cd5a59c3900cd14d Mon Sep 17 00:00:00 2001 From: Teknium Date: Sun, 29 Mar 2026 11:09:17 -0700 Subject: [PATCH] fix: store token lock identity at acquire time for Slack and Discord Community review (devoruncommented) correctly identified that the Slack adapter re-read SLACK_APP_TOKEN from os.getenv() during disconnect, which could differ from the value used during connect if the environment changed. Discord had the same pattern with self.config.token (less risky but still not bulletproof). Both now follow the Telegram pattern: store the token identity on self at acquire time, use the stored value for release, clear after release. Also fixes docs: alias naming was hermes- in docs but actual implementation creates directly (e.g. ~/.local/bin/coder not ~/.local/bin/hermes-coder). --- gateway/platforms/discord.py | 7 +++++-- gateway/platforms/slack.py | 9 +++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/gateway/platforms/discord.py b/gateway/platforms/discord.py index 18e93ce69..1da9925cd 100644 --- a/gateway/platforms/discord.py +++ b/gateway/platforms/discord.py @@ -488,7 +488,8 @@ class DiscordAdapter(BasePlatformAdapter): try: # Acquire scoped lock to prevent duplicate bot token usage from gateway.status import acquire_scoped_lock - acquired, existing = acquire_scoped_lock('discord-bot-token', self.config.token, metadata={'platform': 'discord'}) + self._token_lock_identity = self.config.token + acquired, existing = acquire_scoped_lock('discord-bot-token', self._token_lock_identity, metadata={'platform': 'discord'}) if not acquired: owner_pid = existing.get('pid') if isinstance(existing, dict) else None message = f'Discord bot token already in use' + (f' (PID {owner_pid})' if owner_pid else '') + '. Stop the other gateway first.' @@ -652,7 +653,9 @@ class DiscordAdapter(BasePlatformAdapter): # Release the token lock try: from gateway.status import release_scoped_lock - release_scoped_lock('discord-bot-token', self.config.token) + if getattr(self, '_token_lock_identity', None): + release_scoped_lock('discord-bot-token', self._token_lock_identity) + self._token_lock_identity = None except Exception: pass diff --git a/gateway/platforms/slack.py b/gateway/platforms/slack.py index 35a6145d9..2a7e046f8 100644 --- a/gateway/platforms/slack.py +++ b/gateway/platforms/slack.py @@ -95,6 +95,7 @@ class SlackAdapter(BasePlatformAdapter): try: # Acquire scoped lock to prevent duplicate app token usage from gateway.status import acquire_scoped_lock + self._token_lock_identity = app_token acquired, existing = acquire_scoped_lock('slack-app-token', app_token, metadata={'platform': 'slack'}) if not acquired: owner_pid = existing.get('pid') if isinstance(existing, dict) else None @@ -149,12 +150,12 @@ class SlackAdapter(BasePlatformAdapter): logger.warning("[Slack] Error while closing Socket Mode handler: %s", e, exc_info=True) self._running = False - # Release the token lock + # Release the token lock (use stored identity, not re-read env) try: from gateway.status import release_scoped_lock - app_token = os.getenv("SLACK_APP_TOKEN") - if app_token: - release_scoped_lock('slack-app-token', app_token) + if getattr(self, '_token_lock_identity', None): + release_scoped_lock('slack-app-token', self._token_lock_identity) + self._token_lock_identity = None except Exception: pass