Package
@slack/socket-mode
SDK Version
@slack/socket-mode@3.0.1 (also 3.0.0), undici@7.29.1 as the peer dependency
Node.js Version
v22.12.0 (bundled undici 6.21.0) and v24.21.0 (bundled undici 7.29.1 — the same version as the npm peer, and it still reproduces)
Operating System
macOS 26.6.2
Steps to Reproduce
SlackWebSocket subscribes to undici's undici:websocket:ping / undici:websocket:pong diagnostics channels. Those channels are process-global: every undici WebSocket publishes to them, including Node's built-in global WebSocket, which is a separate copy of undici from the one @slack/socket-mode imports — even when the two are the same version.
pingHandler / pongHandler run isPingPongMessage(message) first, and that guard does message.websocket instanceof WebSocket against the npm undici import. A frame received on any socket that was opened with the global WebSocket fails that instanceof, so the handler logs a WARN before it gets to the message.websocket !== this.websocket check that would have ignored it silently:
https://github.com/slackapi/node-slack-sdk/blob/main/packages/socket-mode/src/SlackWebSocket.ts#L21-L32
https://github.com/slackapi/node-slack-sdk/blob/main/packages/socket-mode/src/SlackWebSocket.ts#L197-L204
So any other library in the process that opens a WebSocket with the global WebSocket and gets pinged by its server produces one [WARN] Received unexpected ping diagnostics message format per ping. In our case that was a Nostr relay client (nostr-tools, which uses the global WebSocket) whose relay sends a keepalive ping every 30s — so a perfectly healthy Slack connection logged that WARN every 30s for as long as it was up. Slack's own pings pass the check and never warn.
Standalone reproduction, no Slack account needed — a local stand-in for apps.connections.open and the Socket Mode server:
mkdir repro && cd repro && npm init -y >/dev/null
npm i @slack/socket-mode@3.0.1 undici@7 ws
node repro.mjs
// repro.mjs
import { createServer } from "node:http";
import { once } from "node:events";
import { SocketModeClient } from "@slack/socket-mode";
import { WebSocketServer } from "ws";
// Enough of Slack for socket-mode to come up: apps.connections.open hands out the
// WebSocket URL, and every connection is greeted with `hello`. The server pings a
// connection only when asked to.
const sockets = [];
const wss = new WebSocketServer({ host: "127.0.0.1", port: 0 });
wss.on("connection", (socket) => {
sockets.push(socket);
socket.send(JSON.stringify({ type: "hello" }));
});
await once(wss, "listening");
const wsUrl = `ws://127.0.0.1:${wss.address().port}/`;
const http = createServer((_req, res) => {
res.setHeader("content-type", "application/json");
res.end(JSON.stringify({ ok: true, url: wsUrl }));
});
http.listen(0, "127.0.0.1");
await once(http, "listening");
const client = new SocketModeClient({
appToken: "xapp-test",
clientOptions: { slackApiUrl: `http://127.0.0.1:${http.address().port}/api/` },
autoReconnectEnabled: false,
});
await client.start();
console.log("socket-mode connected");
// Some other library in the same process opens a WebSocket with Node's built-in
// global `WebSocket` (Node's bundled undici — a different copy from the npm one).
const other = new WebSocket(wsUrl);
await once(other, "open");
// The server pings *that* socket, not Slack's. socket-mode warns.
const pong = once(sockets[1], "pong");
sockets[1].ping();
await pong;
// Slack's own socket is pinged: no warning.
const pong2 = once(sockets[0], "pong");
sockets[0].ping();
await pong2;
other.close();
await client.disconnect();
wss.close();
http.close();
Expected Result
No log output. A ping or pong frame for a socket that is not SlackWebSocket's own is not about Slack, and should be ignored the same way a frame from a second SocketModeClient's socket already is.
Actual Result
socket-mode connected
[WARN] socket-mode:SlackWebSocket:1 Received unexpected ping diagnostics message format
One WARN per ping frame received on the other socket; nothing for the ping on Slack's own socket. Same output on Node 22.12.0 and 24.21.0.
Suggested fix
Check identity before shape: return early when message?.websocket !== this.websocket, then validate payload. A frame that is not for this socket is expected on a shared channel, so it should not be logged at all (or at most at debug). The pongHandler has the same guard and the same problem.
Happy to open a PR if that shape is acceptable.
Package
@slack/socket-mode
SDK Version
@slack/socket-mode@3.0.1 (also 3.0.0), undici@7.29.1 as the peer dependency
Node.js Version
v22.12.0 (bundled undici 6.21.0) and v24.21.0 (bundled undici 7.29.1 — the same version as the npm peer, and it still reproduces)
Operating System
macOS 26.6.2
Steps to Reproduce
SlackWebSocketsubscribes to undici'sundici:websocket:ping/undici:websocket:pongdiagnostics channels. Those channels are process-global: every undiciWebSocketpublishes to them, including Node's built-in globalWebSocket, which is a separate copy of undici from the one@slack/socket-modeimports — even when the two are the same version.pingHandler/pongHandlerrunisPingPongMessage(message)first, and that guard doesmessage.websocket instanceof WebSocketagainst the npmundiciimport. A frame received on any socket that was opened with the globalWebSocketfails thatinstanceof, so the handler logs a WARN before it gets to themessage.websocket !== this.websocketcheck that would have ignored it silently:https://github.com/slackapi/node-slack-sdk/blob/main/packages/socket-mode/src/SlackWebSocket.ts#L21-L32
https://github.com/slackapi/node-slack-sdk/blob/main/packages/socket-mode/src/SlackWebSocket.ts#L197-L204
So any other library in the process that opens a WebSocket with the global
WebSocketand gets pinged by its server produces one[WARN] Received unexpected ping diagnostics message formatper ping. In our case that was a Nostr relay client (nostr-tools, which uses the globalWebSocket) whose relay sends a keepalive ping every 30s — so a perfectly healthy Slack connection logged that WARN every 30s for as long as it was up. Slack's own pings pass the check and never warn.Standalone reproduction, no Slack account needed — a local stand-in for
apps.connections.openand the Socket Mode server:Expected Result
No log output. A ping or pong frame for a socket that is not
SlackWebSocket's own is not about Slack, and should be ignored the same way a frame from a secondSocketModeClient's socket already is.Actual Result
One WARN per ping frame received on the other socket; nothing for the ping on Slack's own socket. Same output on Node 22.12.0 and 24.21.0.
Suggested fix
Check identity before shape: return early when
message?.websocket !== this.websocket, then validatepayload. A frame that is not for this socket is expected on a shared channel, so it should not be logged at all (or at most atdebug). ThepongHandlerhas the same guard and the same problem.Happy to open a PR if that shape is acceptable.