slackapi / slackapi/node-slack-sdk
socket-mode: "Received unexpected ping diagnostics message format" WARN for pings on other libraries' WebSockets in the same process
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 3.4k
- Forks
- 688
- Avg merge
- 15h 31m
- Merged PRs (30d)
- 27
Description
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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in packages/socket-mode/src/SlackWebSocket.ts, especially the pingHandler and pongHandler locations linked in the issue, and run the standalone reproduction to observe the warning. Update the handling so frames from other sockets are ignored before validation; done means the reproduction produces no warning for the other WebSocket while Slack's socket continues to work.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nodejs, typescript
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100