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

  1. Use 1000 for normal closure or 3000-4999 for application-specific codes
  2. Omit the code entirely (ws.close()) for the default 1000 close
  3. 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

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


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/924245e9611175a8. Report an issue: GitHub.