{"record":{"id":"5019d18464787640","repo":"dotnet/aspnetcore","slug":"websocket-is-not-supported-in-your-environment","errorCode":null,"errorMessage":"'WebSocket' is not supported in your environment.","messagePattern":"'WebSocket' is not supported in your environment\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/SignalR/clients/ts/signalr/src/HttpConnection.ts","lineNumber":529,"sourceCode":"                        const message = \"Failed to select transport before stop() was called.\";\n                        this._logger.log(LogLevel.Debug, message);\n                        return Promise.reject(new AbortError(message));\n                    }\n                }\n            }\n        }\n\n        if (transportExceptions.length > 0) {\n            return Promise.reject(new AggregateErrors(`Unable to connect to the server with any of the available transports. ${transportExceptions.join(\" \")}`, transportExceptions));\n        }\n        return Promise.reject(new Error(\"None of the transports supported by the client are supported by the server.\"));\n    }\n\n    private _constructTransport(transport: HttpTransportType): ITransport {\n        switch (transport) {\n            case HttpTransportType.WebSockets:\n                if (!this._options.WebSocket) {\n                    throw new Error(\"'WebSocket' is not supported in your environment.\");\n                }\n                return new WebSocketTransport(this._httpClient, this._accessTokenFactory, this._logger, this._options.logMessageContent!,\n                    this._options.WebSocket, this._options.headers || {});\n            case HttpTransportType.ServerSentEvents:\n                if (!this._options.EventSource) {\n                    throw new Error(\"'EventSource' is not supported in your environment.\");\n                }\n                return new ServerSentEventsTransport(this._httpClient, this._httpClient._accessToken, this._logger, this._options);\n            case HttpTransportType.LongPolling:\n                return new LongPollingTransport(this._httpClient, this._logger, this._options);\n            default:\n                throw new Error(`Unknown transport: ${transport}.`);\n        }\n    }\n\n    private _startTransport(url: string, transferFormat: TransferFormat): Promise<void> {\n        this.transport!.onreceive = this.onreceive;\n        if (this.features.reconnect) {","sourceCodeStart":511,"sourceCodeEnd":547,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/SignalR/clients/ts/signalr/src/HttpConnection.ts#L511-L547","documentation":"Thrown at HttpConnection.ts:529 inside _constructTransport when the WebSockets transport is selected but `options.WebSocket` is falsy. The constructor (lines 110-116) populates this from the global WebSocket in browsers or the `ws` npm module in Node; if neither is available and the user did not supply one, the transport cannot be built.","triggerScenarios":"Running in an unusual JS environment without a global WebSocket (older Node without `ws` installed, some embedded runtimes, a worker context); explicitly setting `options.WebSocket = null` or undefined; the `ws` module failing to load in Node (Platform.isNode true but require threw or returned null).","commonSituations":"Node app where `ws` is not in node_modules; serverless/edge runtime without WebSocket support; bundler that tree-shook the ws require; a test environment (jsdom without WebSocket polyfill) forcing SSE to be skipped.","solutions":["In Node, install the `ws` package: `npm install ws` (and `eventsource` if you need SSE).","In a custom runtime, pass an implementation: `new HttpConnection(url, { WebSocket: MyWebSocketImpl })`.","In browsers, ensure you're not running in a context where the global WebSocket was deleted.","Fall back to a different transport: `withUrl(url, { transport: HttpTransportType.LongPolling })`."],"exampleFix":"// Node without ws installed -> throws\n// fix: install ws\n// npm install ws\n\n// or supply a custom impl\nnew HubConnectionBuilder()\n  .withUrl(url, { transport: HttpTransportType.WebSockets, WebSocket: require('ws') })\n  .build();","handlingStrategy":"validation","validationCode":"function resolveWebSocketImpl() {\n  if (typeof WebSocket !== 'undefined') return WebSocket;\n  try { return require('ws'); } catch { return undefined; }\n}\nconst WS = resolveWebSocketImpl();\nif (!WS) throw new Error('WebSocket unavailable - install ws or pick another transport');\nconst options = { transport: HttpTransportType.WebSockets, WebSocket: WS };","typeGuard":"function isWebSocketCtor(v: unknown): v is { new (url: string): any } {\n  return typeof v === 'function';\n}","tryCatchPattern":"try { await conn.start(transferFormat); }\ncatch (e) {\n  if (/'WebSocket' is not supported/.test(String(e))) {\n    // fall back to LongPolling\n    return new HttpConnection(url, { ...options, transport: HttpTransportType.LongPolling, WebSocket: undefined }).start(transferFormat);\n  }\n  throw e;\n}","preventionTips":["In Node, add `ws` to dependencies whenever you select the WebSockets transport.","Pass an explicit WebSocket implementation in options to remove ambient-global ambiguity.","Provide a transport fallback chain in your connection helper."],"tags":["transport","websocket","environment","node","polyfill"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}