{"record":{"id":"1287e8aa4835903c","repo":"denoland/deno","slug":"syntaxerror-1287e8","errorCode":"SyntaxError","errorMessage":"Only ws & wss schemes are allowed in a WebSocket URL.","messagePattern":"Only ws & wss schemes are allowed in a WebSocket URL\\.","errorType":"exception","errorClass":"DOMException","httpStatus":null,"severity":"error","filePath":"ext/websocket/02_websocketstream.js","lineNumber":120,"sourceCode":"    webidl.assertBranded(this, WebSocketStreamPrototype);\n    return this[_url];\n  }\n\n  constructor(url, options) {\n    this[webidl.brand] = webidl.brand;\n    const prefix = \"Failed to construct 'WebSocketStream'\";\n    webidl.requiredArguments(arguments.length, 1, prefix);\n    url = webidl.converters.USVString(url, prefix, \"Argument 1\");\n    options = webidl.converters.WebSocketStreamOptions(\n      options,\n      prefix,\n      \"Argument 2\",\n    );\n\n    const wsURL = new URL(url);\n\n    if (wsURL.protocol !== \"ws:\" && wsURL.protocol !== \"wss:\") {\n      throw new DOMException(\n        \"Only ws & wss schemes are allowed in a WebSocket URL.\",\n        \"SyntaxError\",\n      );\n    }\n\n    if (wsURL.hash !== \"\" || StringPrototypeEndsWith(wsURL.href, \"#\")) {\n      throw new DOMException(\n        \"Fragments are not allowed in a WebSocket URL.\",\n        \"SyntaxError\",\n      );\n    }\n\n    this[_url] = wsURL.href;\n\n    if (\n      options.protocols.length !==\n        SetPrototypeGetSize(\n          new SafeSet(","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/websocket/02_websocketstream.js#L102-L138","documentation":"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).","triggerScenarios":"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.","commonSituations":"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).","solutions":["Rewrite the scheme yourself: url.replace(/^http/, 'ws')","Store or compute ws:// / wss:// URLs specifically for WebSocketStream usage","Pass an absolute URL - WebSocketStream does not resolve against the document base"],"exampleFix":"// before\nnew WebSocketStream(`http://${host}/ws`);\n\n// after\nnew WebSocketStream(`ws://${host}/ws`);","handlingStrategy":"validation","validationCode":"function toWsStreamUrl(raw: string): string {\n  const u = new URL(raw); // no base resolution - must be absolute\n  if (u.protocol === 'http:') u.protocol = 'ws:';\n  else if (u.protocol === 'https:') u.protocol = 'wss:';\n  return u.href;\n}\nnew WebSocketStream(toWsStreamUrl(url));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["WebSocketStream never auto-upgrades schemes - normalize http/https to ws/wss yourself","Pass absolute URLs; no base URL is applied","Keep one URL-normalizing helper shared by WebSocket and WebSocketStream code"],"tags":["websocketstream","url-scheme","syntaxerror","domexception"],"backgroundTag":"invalid-url-scheme","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}