denoland/deno · error · DOMException
InvalidAccessError
InvalidAccessError
Error message
The close code must be either 1000 or in the range of 3000 to 4999: received ${code} What it means
ws.close(code, reason) validates the code only for client-role sockets (this[_role] === CLIENT): it must be exactly 1000 or in 3000..4999. Anything else - 1001, 1011, 2000, 5000, 0, negatives - throws InvalidAccessError. Codes 1001-1015 are reserved for the peer/OS and cannot be set from client JS.
Source
Thrown at ext/websocket/01_websocket.js:701
webidl.assertBranded(this, WebSocketPrototype);
const prefix = "Failed to execute 'close' on 'WebSocket'";
if (code !== undefined) {
code = webidl.converters["unsigned short"](code, prefix, "Argument 1", {
clamp: true,
});
}
if (reason !== undefined) {
reason = webidl.converters.USVString(reason, prefix, "Argument 2");
}
if (this[_role] === CLIENT) {
if (
code !== undefined &&
!(code === 1000 || (3000 <= code && code < 5000))
) {
throw new DOMException(
`The close code must be either 1000 or in the range of 3000 to 4999: received ${code}`,
"InvalidAccessError",
);
}
}
if (
reason !== undefined &&
TypedArrayPrototypeGetByteLength(core.encode(reason)) > 123
) {
throw new DOMException(
"The close reason may not be longer than 123 bytes",
"SyntaxError",
);
}
if (this[_cancelHandle]) {
// Cancel ongoing handshake.View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Use 1000 for normal closure or 3000-4999 for application-specific codes
- Omit the code entirely (ws.close()) for the default 1000 close
- Let the server send 1001/1011 - the client side cannot
Example fix
// before ws.close(1001, 'going away'); // after ws.close(1000, 'going away'); // or a custom code like 4000
Defensive patterns
Strategy: validation
Validate before calling
const isValidCloseCode = (code?: number): boolean =>
code === undefined || code === 1000 || (code >= 3000 && code <= 4999);
if (!isValidCloseCode(code)) throw new RangeError(`bad close code: ${code}`); Prevention
- Only 1000 and 3000-4999 are settable from client JS
- Keep application close codes in a shared 4000-4999 registry
- Never map HTTP status codes onto close codes
When it happens
Trigger: ws.close(1001, 'going away'), ws.close(1011), ws.close(2000), ws.close(5000), or passing 0 because no code was intended.
Common situations: Copying close codes from server logs into client code; using HTTP status codes (404, 500) as close codes; assuming all 1xxx codes are settable.
Related errors
- InvalidAccessError
- BenchContext::start() has already been invoked
- ${prefix}Linter plugin name must only contain lowercase lett
- ${prefix}Linter plugin name must start and end with a lowerc
- ${prefix}Linter plugin name must not have consequtive hyphen
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/924245e9611175a8.
Report an issue: GitHub.