denoland/deno · error · DOMException

SyntaxError

SyntaxError

Error message

Only ws & wss schemes are allowed in a WebSocket URL.

What it means

new WebSocketStream(url) parses with new URL(url) - no base URL and, unlike the WebSocket constructor, no http:->ws: / https:->wss: auto-upgrade. The scheme must already be ws: or wss:, otherwise a SyntaxError DOMException is thrown (this message ends with a period, unlike the WebSocket variant).

Source

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

    webidl.assertBranded(this, WebSocketStreamPrototype);
    return this[_url];
  }

  constructor(url, options) {
    this[webidl.brand] = webidl.brand;
    const prefix = "Failed to construct 'WebSocketStream'";
    webidl.requiredArguments(arguments.length, 1, prefix);
    url = webidl.converters.USVString(url, prefix, "Argument 1");
    options = webidl.converters.WebSocketStreamOptions(
      options,
      prefix,
      "Argument 2",
    );

    const wsURL = new URL(url);

    if (wsURL.protocol !== "ws:" && wsURL.protocol !== "wss:") {
      throw new DOMException(
        "Only ws & wss schemes are allowed in a WebSocket URL.",
        "SyntaxError",
      );
    }

    if (wsURL.hash !== "" || StringPrototypeEndsWith(wsURL.href, "#")) {
      throw new DOMException(
        "Fragments are not allowed in a WebSocket URL.",
        "SyntaxError",
      );
    }

    this[_url] = wsURL.href;

    if (
      options.protocols.length !==
        SetPrototypeGetSize(
          new SafeSet(

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Rewrite the scheme yourself: url.replace(/^http/, 'ws')
  2. Store or compute ws:// / wss:// URLs specifically for WebSocketStream usage
  3. Pass an absolute URL - WebSocketStream does not resolve against the document base

Example fix

// before
new WebSocketStream(`http://${host}/ws`);

// after
new WebSocketStream(`ws://${host}/ws`);
Defensive patterns

Strategy: validation

Validate before calling

function toWsStreamUrl(raw: string): string {
  const u = new URL(raw); // no base resolution - must be absolute
  if (u.protocol === 'http:') u.protocol = 'ws:';
  else if (u.protocol === 'https:') u.protocol = 'wss:';
  return u.href;
}
new WebSocketStream(toWsStreamUrl(url));

Prevention

When it happens

Trigger: new WebSocketStream('http://localhost:8080/ws') - fine for WebSocket (upgraded) but throwing here; reusing an http:// config URL or location-based URL without rewriting the scheme.

Common situations: Porting WebSocket code to WebSocketStream and assuming identical scheme handling; configs that store http:// URLs; relative URLs (they fail as 'Invalid URL' since no base is passed).

Understand the failure class

Background: SyntaxError: 'Unexpected token' and 'Unexpected end of input' — why parsers reject your input across libraries — this error's family across 24 libraries.

Related errors


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