{"record":{"id":"bcc03068003ec1f3","repo":"websockets/ws","slug":"the-message-must-not-be-greater-than-123-bytes","errorCode":null,"errorMessage":"The message must not be greater than 123 bytes","messagePattern":"The message must not be greater than 123 bytes","errorType":"exception","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"lib/sender.js","lineNumber":198,"sourceCode":"   * @param {Boolean} [mask=false] Specifies whether or not to mask the message\n   * @param {Function} [cb] Callback\n   * @public\n   */\n  close(code, data, mask, cb) {\n    let buf;\n\n    if (code === undefined) {\n      buf = EMPTY_BUFFER;\n    } else if (typeof code !== 'number' || !isValidStatusCode(code)) {\n      throw new TypeError('First argument must be a valid error code number');\n    } else if (data === undefined || !data.length) {\n      buf = Buffer.allocUnsafe(2);\n      buf.writeUInt16BE(code, 0);\n    } else {\n      const length = Buffer.byteLength(data);\n\n      if (length > 123) {\n        throw new RangeError('The message must not be greater than 123 bytes');\n      }\n\n      buf = Buffer.allocUnsafe(2 + length);\n      buf.writeUInt16BE(code, 0);\n\n      if (typeof data === 'string') {\n        buf.write(data, 2);\n      } else if (isUint8Array(data)) {\n        buf.set(data, 2);\n      } else {\n        throw new TypeError('Second argument must be a string or a Uint8Array');\n      }\n    }\n\n    const options = {\n      [kByteLength]: buf.length,\n      fin: true,\n      generateMask: this._generateMask,","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/websockets/ws/blob/c791e707eab3c13dd9a261d2479c3cc4a49a6fed/lib/sender.js#L180-L216","documentation":"Thrown by Sender.close() when the UTF-8 byte length of the close-frame reason string exceeds 123 bytes. RFC 6455 caps all control frame (opcode 0x08) payloads at 125 bytes; the first 2 bytes carry the status code, leaving only 123 bytes for the human-readable reason. The library enforces this in sender.js:195-198 before attempting to build the frame, so an oversized reason never reaches the wire.","triggerScenarios":"Calling ws.close(code, reason) or the internal sender.close(code, data, mask, cb) where Buffer.byteLength(data) > 123. The check fires only when both a numeric code and a non-empty data argument are supplied (code !== undefined and data.length > 0), because the 123-byte limit applies to the reason body that follows the 2-byte status code.","commonSituations":"Passing a long diagnostic/stack-trace/error description as the close reason during graceful shutdown; internationalized reason strings whose multi-byte UTF-8 encoding exceeds 123 bytes even though the character count looks short; copying exception messages verbatim into ws.close() without truncation.","solutions":["Truncate the reason to at most 123 bytes before calling close(): use reason = Buffer.from(reason).subarray(0, 123).toString() or slice the string so Buffer.byteLength(reason) <= 123.","If you only need a status code, omit the reason entirely: ws.close(1000).","Send lengthy diagnostic details via a preceding normal data message (ws.send) before closing, then close with a short or empty reason."],"exampleFix":"// before\nws.close(1000, longErrorStackMessage);\n\n// after\nconst reason = Buffer.from(longErrorStackMessage).subarray(0, 123).toString();\nws.close(1000, reason);","handlingStrategy":"validation","validationCode":"// Run before ws.close(code, reason) or sender.close()\nfunction safeCloseReason(reason) {\n  if (reason == null) return undefined;\n  const buf = Buffer.from(reason);\n  return buf.length > 123 ? buf.subarray(0, 123).toString() : reason;\n}\n// usage: ws.close(1000, safeCloseReason(longMessage));","typeGuard":"function isValidCloseReason(data) {\n  return (\n    typeof data === 'string' ||\n    (data != null && typeof data === 'object' && ArrayBuffer.isView(data) && data.BYTES_PER_ELEMENT === 1)\n  ); // string or Uint8Array/Buffer\n}","tryCatchPattern":"try {\n  ws.close(code, reason);\n} catch (err) {\n  if (err instanceof RangeError && /123 bytes/.test(err.message)) {\n    ws.close(code, String(reason).slice(0, 123));\n  } else {\n    throw err;\n  }\n}","preventionTips":["Always truncate close reasons to <= 123 bytes; use Buffer.byteLength to measure multi-byte strings.","Omit the reason argument when you only need a status code.","Send lengthy diagnostics via ws.send() before closing instead of stuffing them into the close frame."],"tags":["websocket","close-frame","rfc6455","validation","control-frame"],"backgroundTag":null,"analyzedSha":"c791e707eab3c13dd9a261d2479c3cc4a49a6fed","analyzedAt":"2026-08-06T19:07:51.047Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}