{"record":{"id":"e127a1f6a1af731a","repo":"websockets/ws","slug":"second-argument-must-be-a-string-or-a-uint8array","errorCode":null,"errorMessage":"Second argument must be a string or a Uint8Array","messagePattern":"Second argument must be a string or a Uint8Array","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/sender.js","lineNumber":209,"sourceCode":"    } 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,\n      mask,\n      maskBuffer: this._maskBuffer,\n      opcode: 0x08,\n      readOnly: false,\n      rsv1: false\n    };\n\n    if (this._state !== DEFAULT) {\n      this.enqueue([this.dispatch, buf, false, options, cb]);\n    } else {\n      this.sendFrame(Sender.frame(buf, options), cb);","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/websockets/ws/blob/c791e707eab3c13dd9a261d2479c3cc4a49a6fed/lib/sender.js#L191-L227","documentation":"Thrown by Sender.close() at sender.js:206-210 when the reason argument (the second parameter, `data`) is neither a string nor a Uint8Array (which includes Node Buffers). The library only knows how to write these two representations into the close frame body, so any other type is rejected. The check is reached only when a valid numeric code is present and data is non-empty.","triggerScenarios":"Calling ws.close(code, data) / sender.close(code, data, mask, cb) where data is a number, plain object, array, null-wrapped value, or any non-Uint8Array typed array. The isUint8Array check from util.types at sender.js:206 returns false, triggering the TypeError.","commonSituations":"Passing a number as reason (e.g. ws.close(1000, 42)); passing an object like {message: '...'} from a JSON error serializer; passing an ArrayBuffer (which is NOT a Uint8Array) instead of a Uint8Array/Buffer view; accidentally swapping the code and data arguments.","solutions":["Coerce the reason to a string: ws.close(1000, String(reason)) or ws.close(1000, JSON.stringify(obj)).","If you have an ArrayBuffer, wrap it: ws.close(1000, new Uint8Array(arrayBuffer)).","Verify the argument order: ws.close(statusCode, reasonString) — code first, reason second."],"exampleFix":"// before\nws.close(1000, { detail: 'shutting down' });\n\n// after\nws.close(1000, JSON.stringify({ detail: 'shutting down' }));","handlingStrategy":"validation","validationCode":"const { isUint8Array } = require('util');\nfunction coerceCloseReason(data) {\n  if (data == null) return undefined;\n  if (typeof data === 'string') return data;\n  if (isUint8Array(data)) return data;\n  return String(data); // or JSON.stringify(data) for objects\n}","typeGuard":"const { isUint8Array } = require('util');\nfunction isCloseReasonAcceptable(data) {\n  return typeof data === 'string' || isUint8Array(data);\n}","tryCatchPattern":"try {\n  ws.close(code, data);\n} catch (err) {\n  if (err instanceof TypeError && /string or a Uint8Array/.test(err.message)) {\n    ws.close(code, String(data));\n  } else {\n    throw err;\n  }\n}","preventionTips":["Always coerce non-string reasons to string or Buffer before calling close().","Wrap ArrayBuffers in new Uint8Array(ab) before passing.","Double-check argument order: (statusCode, reason)."],"tags":["websocket","close-frame","type-error","validation","typescript"],"backgroundTag":null,"analyzedSha":"c791e707eab3c13dd9a261d2479c3cc4a49a6fed","analyzedAt":"2026-08-06T19:07:51.047Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}