Skip to content

fix(socket-mode): route ping/pong diagnostics by identity, not instanceof (#2743) - #2747

Open
WilliamBergamin wants to merge 5 commits into
mainfrom
fix-issue-2743
Open

WilliamBergamin wants to merge 5 commits into
mainfrom
fix-issue-2743

Conversation

@WilliamBergamin

Copy link
Copy Markdown
Contributor

Summary

Fixes #2743.

@slack/socket-mode drives its heartbeat by subscribing to undici's undici:websocket:ping / undici:websocket:pong diagnostics channels. Those channels are process-global: every undici WebSocket in the process publishes to them, including Node's built-in global WebSocket, which is a separate copy of undici from the one the SDK imports (even at the same version).

In SlackWebSocket.ts, pingHandler/pongHandler ran isPingPongMessage(message) first, and that guard required message.websocket instanceof WebSocket against the SDK's undici import. A frame from a socket opened by any other undici copy fails that instanceof, so the handler logged Received unexpected ping diagnostics message format at WARN before reaching the message.websocket !== this.websocket identity check that would have dropped it silently.

Result: any library in the same process that opens a WebSocket via the global WebSocket and receives pings makes a healthy Slack connection spam one WARN per foreign ping. (The reporter hit this with a nostr-tools relay pinging every 30s.)

The fix: match by reference identity (message.websocket === this.websocket) instead of instanceof, and fold identity + shape into one guard that returns silently for frames that are not this socket's. instanceof was only ever a proxy for identity, and it is cross-copy-fragile; reference equality is strictly stronger for routing and was already being computed one line too late. Slack's own frames pass exactly as before, so heartbeat behavior is unchanged.

Adds unit tests (the first to exercise the diagnostics-channel path) covering both channels: a frame from a foreign undici copy is ignored with no WARN, and a frame for this socket is processed.

Requirements

…ceof (#2743)

The undici ping/pong diagnostics channels are process-global: every undici
WebSocket in the process publishes to them, including Node's built-in global
WebSocket, which is a separate undici copy from the SDK's import. The old guard
checked `message.websocket instanceof WebSocket` before the identity check, so a
frame from any other undici copy failed instanceof and logged a spurious WARN on
an otherwise healthy Slack connection (issue reporter: a nostr-tools relay
pinging every 30s).

Match by reference identity (`message.websocket === this.websocket`) instead,
folding identity and shape into one guard that returns silently for frames that
are not this socket's. Slack's own frames are unaffected. Adds tests covering
foreign-copy and same-socket frames on both channels.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
@changeset-bot

changeset-bot Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: efabc23

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@slack/socket-mode Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codecov

codecov Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.71429% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 89.28%. Comparing base (334e6a6) to head (efabc23).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2747      +/-   ##
==========================================
+ Coverage   89.15%   89.28%   +0.12%     
==========================================
  Files          65       65              
  Lines       10442    10433       -9     
  Branches      480      478       -2     
==========================================
+ Hits         9310     9315       +5     
+ Misses       1100     1087      -13     
+ Partials       32       31       -1     
Flag Coverage Δ
cli-hooks 89.22% <85.71%> (+0.10%) ⬆️
cli-test 89.22% <85.71%> (+0.10%) ⬆️
logger 89.22% <85.71%> (+0.10%) ⬆️
oauth 89.22% <85.71%> (+0.10%) ⬆️
socket-mode 89.22% <85.71%> (+0.10%) ⬆️
web-api 89.22% <85.71%> (+0.10%) ⬆️
webhook 89.22% <85.71%> (+0.10%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

WilliamBergamin and others added 2 commits September 22, 2026 13:10
…cket

Same logic, expressed as early-return if statements instead of one boolean
chain. Reads more clearly and matches the guard shape the file used before.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
The function name and guard clauses carry the intent; the comment was redundant.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
@WilliamBergamin WilliamBergamin self-assigned this Sep 22, 2026
@WilliamBergamin WilliamBergamin added bug M-T: A confirmed bug report. Issues are confirmed when the reproduction steps are documented semver:patch pkg:socket-mode applies to `@slack/socket-mode` labels Sep 22, 2026
@WilliamBergamin WilliamBergamin added this to the socket-mode@next milestone Sep 22, 2026
@WilliamBergamin
WilliamBergamin marked this pull request as ready for review September 22, 2026 17:17
@WilliamBergamin
WilliamBergamin requested a review from a team as a code owner September 22, 2026 17:17

This branch has not been deployed

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

Labels

bug M-T: A confirmed bug report. Issues are confirmed when the reproduction steps are documented pkg:socket-mode applies to `@slack/socket-mode` semver:patch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

socket-mode: "Received unexpected ping diagnostics message format" WARN for pings on other libraries' WebSockets in the same process

1 participant