denoland/deno · error · DOMException

InvalidAccessError

InvalidAccessError

Error message

The close code must be either 1000 or in the range of 3000 to 4999.

What it means

validateCloseCodeAndReason checks closeInfo.closeCode for WebSocketStream.close({ closeCode, reason }): falsy values become null (no code sent); otherwise the code must be exactly 1000 or in 3000..4999, else an InvalidAccessError DOMException is thrown. A separate 123-byte reason check follows it.

Source

Thrown at ext/websocket/02_websocketstream.js:460

        ],
      }),
      inspectOptions,
    );
  }
}
const WebSocketStreamPrototype = WebSocketStream.prototype;

function validateCloseCodeAndReason(closeInfo) {
  if (!closeInfo.closeCode) {
    closeInfo.closeCode = null;
  }

  if (
    closeInfo.closeCode &&
    !(closeInfo.closeCode === 1000 ||
      (3000 <= closeInfo.closeCode && closeInfo.closeCode < 5000))
  ) {
    throw new DOMException(
      "The close code must be either 1000 or in the range of 3000 to 4999.",
      "InvalidAccessError",
    );
  }

  const encoder = new TextEncoder();
  if (
    closeInfo.reason &&
    TypedArrayPrototypeGetByteLength(encoder.encode(closeInfo.reason)) > 123
  ) {
    throw new DOMException(
      "The close reason may not be longer than 123 bytes.",
      "SyntaxError",
    );
  }
}

class WebSocketError extends DOMException {

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Use 1000 or a 3000-4999 application code
  2. Omit closeCode entirely for the default close
  3. Define shared app close-code constants in the 4000-4999 range

Example fix

// before
wss.close({ closeCode: 1001, reason: 'going away' });

// after
wss.close({ closeCode: 1000, reason: 'going away' });
Defensive patterns

Strategy: validation

Validate before calling

const isValidCloseCode = (code?: number | null): boolean =>
  !code || code === 1000 || (code >= 3000 && code <= 4999);
if (!isValidCloseCode(closeInfo.closeCode)) {
  closeInfo = { ...closeInfo, closeCode: 1000 };
}

Prevention

When it happens

Trigger: wss.close({ closeCode: 1001 }), { closeCode: 2000 }, { closeCode: 5000 }, or { closeCode: 0 } - reserved/system codes are not settable by the closing side.

Common situations: Reusing 1001/1011 codes seen in server logs for client-initiated closes; copying numeric codes from other protocols; passing 0 as a sentinel.

Related errors


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