Skip to content

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

Description

@shrimalmadhur

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.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions