websockets/ws · error · TypeError
First argument must be a valid error code number
Error message
First argument must be a valid error code number
What it means
Thrown as a TypeError by Sender.close() (sender.js:189-190) when the code argument is provided but is either not a number or fails isValidStatusCode(). Valid status codes per WebSocket close-frame rules (RFC 6455 §7.4) are: 1000-1014 (excluding 1004, 1005, 1006), and 3000-4999. Any other value — such as 0, 200, 1005, 9999, a string, or null — causes this synchronous throw that propagates to the caller of ws.close().
Source
Thrown at lib/sender.js:190
return [target, data];
}
/**
* Sends a close message to the other peer.
*
* @param {Number} [code] The status code component of the body
* @param {(String|Buffer)} [data] The message component of the body
* @param {Boolean} [mask=false] Specifies whether or not to mask the message
* @param {Function} [cb] Callback
* @public
*/
close(code, data, mask, cb) {
let buf;
if (code === undefined) {
buf = EMPTY_BUFFER;
} else if (typeof code !== 'number' || !isValidStatusCode(code)) {
throw new TypeError('First argument must be a valid error code number');
} else if (data === undefined || !data.length) {
buf = Buffer.allocUnsafe(2);
buf.writeUInt16BE(code, 0);
} else {
const length = Buffer.byteLength(data);
if (length > 123) {
throw new RangeError('The message must not be greater than 123 bytes');
}
buf = Buffer.allocUnsafe(2 + length);
buf.writeUInt16BE(code, 0);
if (typeof data === 'string') {
buf.write(data, 2);
} else if (isUint8Array(data)) {
buf.set(data, 2);
} else {View on GitHub (pinned to ae1de54330)
Solutions
- Use a valid WebSocket close code: 1000-1014 (except 1004/1005/1006) or 3000-4999.
- Ensure the code argument is a number, not a string — convert with Number() or parseInt() before calling close().
- Omit the code argument entirely (call ws.close() with no arguments) to send a close frame with no status code.
- If you need application-specific codes, use the 3000-4999 range.
Example fix
// before — invalid code (reserved) ws.close(1005, 'going away'); // after — use a valid sendable code ws.close(1001, 'going away');
Defensive patterns
Strategy: validation
Validate before calling
const { isValidStatusCode } = require('ws/lib/validation');
function closeSafely(ws, code, reason) {
if (code === undefined || code === null) {
ws.close();
return;
}
if (typeof code !== 'number' || !isValidStatusCode(code)) {
throw new TypeError(`Invalid close code: ${code}`);
}
ws.close(code, reason);
} Type guard
function isValidCloseCode(code) {
return (
typeof code === 'number' &&
((code >= 1000 && code <= 1014 && code !== 1004 && code !== 1005 && code !== 1006) ||
(code >= 3000 && code <= 4999))
);
} Try / catch
try {
ws.close(code, reason);
} catch (err) {
if (err instanceof TypeError && err.message.includes('valid error code')) {
// Fall back to a generic normal closure
console.warn(`Invalid close code ${code}; closing with 1000 instead.`);
ws.close(1000, reason);
} else {
throw err;
}
} Prevention
- Always validate the close code against the allowed ranges (1000-1014 except 1004/1005/1006, or 3000-4999) before calling ws.close().
- Ensure code is a number, not a string — convert with Number() if it comes from user input.
- Omit the code argument entirely when you want a close frame with no status body.
- Use the 3000-4999 range for application-specific close codes.
- Never use 1005 or 1006 — those are reserved for internal use and cannot appear in a close frame.
When it happens
Trigger: Calling ws.close(code) or ws.close(code, reason) where code is a non-number (e.g. a string '1000', undefined paired with a reason, null) or a number outside the valid ranges. Internally, WebSocket.close() at websocket.js:322 passes code directly to sender.close(), so the throw surfaces synchronously from the ws.close() call site.
Common situations: A developer passes a custom error code like 200 or 6000 which is outside the allowed ranges. Someone passes code as a string instead of a number. A developer uses 1005/1006 (reserved/forbidden codes) thinking they are sendable. Passing null or 0 as a code. Confusing application-level error codes with WebSocket close codes.
Related errors
- Invalid value for parameter "${key}": ${value}
- Unknown parameter "${key}"
- ws does not work in the browser. Browser clients must use th
- Unexpected character at index ${i}
- Unexpected end of input
AI-assisted analysis of websockets/ws@ae1de54330 (2026-08-03).
Data as JSON: /data/errors/21fd53d0970da278.json.
Report an issue: GitHub.