{"id":"85adf974922b5521","repo":"websockets/ws","slug":"websocket-is-not-open-readystate-0-connecting","errorCode":null,"errorMessage":"WebSocket is not open: readyState 0 (CONNECTING)","messagePattern":"WebSocket is not open: readyState 0 \\(CONNECTING\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/websocket.js","lineNumber":369,"sourceCode":"    ) {\n      return;\n    }\n\n    this._paused = true;\n    this._socket.pause();\n  }\n\n  /**\n   * Send a ping.\n   *\n   * @param {*} [data] The data to send\n   * @param {Boolean} [mask] Indicates whether or not to mask `data`\n   * @param {Function} [cb] Callback which is executed when the ping is sent\n   * @public\n   */\n  ping(data, mask, cb) {\n    if (this.readyState === WebSocket.CONNECTING) {\n      throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n    }\n\n    if (typeof data === 'function') {\n      cb = data;\n      data = mask = undefined;\n    } else if (typeof mask === 'function') {\n      cb = mask;\n      mask = undefined;\n    }\n\n    if (typeof data === 'number') data = data.toString();\n\n    if (this.readyState !== WebSocket.OPEN) {\n      sendAfterClose(this, data, cb);\n      return;\n    }\n\n    if (mask === undefined) mask = !this._isServer;","sourceCodeStart":351,"sourceCodeEnd":387,"githubUrl":"https://github.com/websockets/ws/blob/ae1de54330cef77e487548890fabfeb9aae1d83d/lib/websocket.js#L351-L387","documentation":"Thrown by WebSocket.prototype.ping() (lib/websocket.js:367-370) when called while readyState is CONNECTING (0), i.e. before the opening handshake has completed. The underlying Sender has no usable socket state yet and the library refuses to queue a control frame for a connection that may never open. Note: if readyState is CLOSING or CLOSED, ping() does NOT throw but silently calls sendAfterClose() and reports the error via the callback; the throw is specific to the CONNECTING state.","triggerScenarios":"Calling ws.ping(...) immediately after `new WebSocket(url)` synchronously, or inside a non-'open' handler, before the 'open' event fires. The check at line 368 throws synchronously.","commonSituations":"Sending an initial heartbeat before the connection is established; calling ping in the constructor or in a module-init path; reusing a WebSocket reference across reconnect attempts where the new socket is still CONNECTING.","solutions":["Wait for the 'open' event before pinging: ws.on('open', () => ws.ping());.","Guard with readyState: if (ws.readyState === WebSocket.OPEN) ws.ping();.","Use the callback form after open so post-close failures are reported via cb instead of throwing."],"exampleFix":"// before\nconst ws = new WebSocket(url);\nws.ping(); // throws, still CONNECTING\n\n// after\nconst ws = new WebSocket(url);\nws.on('open', () => ws.ping());","handlingStrategy":"validation","validationCode":"function pingWhenOpen(ws, data, cb) {\n  if (ws.readyState !== ws.OPEN) return; // or queue and flush on 'open'\n  ws.ping(data, cb);\n}","typeGuard":"function isOpen(ws) {\n  return ws.readyState === ws.OPEN; // 1\n}","tryCatchPattern":"try {\n  ws.ping(data, cb);\n} catch (err) {\n  if (/CONNECTING/.test(err.message)) {\n    ws.once('open', () => ws.ping(data, cb));\n  } else {\n    throw err;\n  }\n}","preventionTips":["Send pings only after the 'open' event.","Guard with ws.readyState === WebSocket.OPEN.","Drive heartbeats from a timer started in the 'open' handler."],"tags":["websocket","client","lifecycle","readystate","ping"],"analyzedSha":"ae1de54330cef77e487548890fabfeb9aae1d83d","analyzedAt":"2026-08-03T19:11:18.437Z","schemaVersion":2}