websockets/ws · error · SyntaxError

Invalid URL: ${address}

Error message

Invalid URL: ${address}

What it means

Thrown by initAsClient() (lib/websocket.js:706-711) when the address argument cannot be parsed by `new URL(address)`. The constructor first tries to interpret address as a URL; if that throws, ws wraps it in SyntaxError('Invalid URL: ' + address). Note this fires before the protocol is validated, so even a parseable but wrong-scheme URL will produce a different error ('The URL\'s protocol must be one of ...'); this specific message means URL parsing itself failed.

Source

Thrown at lib/websocket.js:709

  websocket._autoPong = opts.autoPong;
  websocket._closeTimeout = opts.closeTimeout;

  if (!protocolVersions.includes(opts.protocolVersion)) {
    throw new RangeError(
      `Unsupported protocol version: ${opts.protocolVersion} ` +
        `(supported versions: ${protocolVersions.join(', ')})`
    );
  }

  let parsedUrl;

  if (address instanceof URL) {
    parsedUrl = address;
  } else {
    try {
      parsedUrl = new URL(address);
    } catch {
      throw new SyntaxError(`Invalid URL: ${address}`);
    }
  }

  if (parsedUrl.protocol === 'http:') {
    parsedUrl.protocol = 'ws:';
  } else if (parsedUrl.protocol === 'https:') {
    parsedUrl.protocol = 'wss:';
  }

  websocket._url = parsedUrl.href;

  const isSecure = parsedUrl.protocol === 'wss:';
  const isIpcUrl = parsedUrl.protocol === 'ws+unix:';
  let invalidUrlMessage;

  if (parsedUrl.protocol !== 'ws:' && !isSecure && !isIpcUrl) {
    invalidUrlMessage =
      'The URL\'s protocol must be one of "ws:", "wss:", ' +

View on GitHub (pinned to ae1de54330)

Solutions

  1. Always include a scheme: 'ws://host:port/path' or 'wss://host/path'.
  2. Construct the URL with `new URL(...)` yourself before passing it (or pass a URL object, which skips the failing branch).
  3. Validate user/config input and reject or fix missing schemes upstream.

Example fix

// before
new WebSocket('localhost:8080/chat');

// after
new WebSocket('ws://localhost:8080/chat');
Defensive patterns

Strategy: validation

Validate before calling

function parseWsUrl(address) {
  let url;
  try {
    url = address instanceof URL ? address : new URL(address);
  } catch {
    throw new SyntaxError(`Invalid URL: ${address}`);
  }
  if (url.protocol === 'http:') url.protocol = 'ws:';
  else if (url.protocol === 'https:') url.protocol = 'wss:';
  if (!['ws:', 'wss:', 'ws+unix:'].includes(url.protocol)) {
    throw new SyntaxError('Unsupported scheme');
  }
  return url;
}

Type guard

function isParseableWsUrl(address) {
  try {
    const u = address instanceof URL ? address : new URL(address);
    return ['ws:', 'wss:', 'http:', 'https:', 'ws+unix:'].includes(u.protocol);
  } catch {
    return false;
  }
}

Try / catch

try {
  new WebSocket(address);
} catch (err) {
  if (/Invalid URL/.test(err.message)) {
    // fix the scheme/encoding and retry, or surface to user
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Calling new WebSocket(someString) where someString is not a valid URL (missing scheme, unencoded spaces, malformed host), e.g. 'localhost:8080' (no scheme), 'wss://', or user input that was never validated.

Common situations: Omitting the ws:// or wss:// scheme; building URLs via string concatenation without encoding; reading the URL from untrusted config/env vars; passing a host:port pair without a protocol.

Related errors


AI-assisted analysis of websockets/ws@ae1de54330 (2026-08-03). Data as JSON: /data/errors/dc0091bb3984f289.json. Report an issue: GitHub.