OrchardCMS/OrchardCore · error · Error

'EventSource' is not supported in your environment.

Error message

'EventSource' is not supported in your environment.

What it means

The SignalR JavaScript client's HttpConnection only knows how to create a transport when the runtime provides the required browser API. When the negotiated transport is ServerSentEvents but no EventSource constructor is available (either not injected via options or running in a non-browser environment without EventSource), it throws this Error.

Solutions

  1. Use the WebSocket or LongPolling transport instead of ServerSentEvents (configure HttpConnectionOptions or let negotiation pick WebSocket).
  2. In non-browser environments, provide an EventSource polyfill via options: new HubConnectionBuilder().withUrl(url, { EventSource: require('eventsource') }).
  3. Run the client in a normal browser context where window.EventSource exists.
  4. Check navigator/feature detection before choosing the SSE transport.

Example fix

// before
const conn = new signalR.HubConnectionBuilder().withUrl(url, { transport: signalR.HttpTransportType.ServerSentEvents }).build();
// after
const conn = new signalR.HubConnectionBuilder().withUrl(url, { transport: signalR.HttpTransportType.WebSockets }).build();
// or in Node:
// withUrl(url, { EventSource: require('eventsource') })
Defensive patterns

Strategy: fallback

Validate before calling

// before choosing SSE
if (typeof EventSource === 'undefined') {
  throw new Error('EventSource unavailable: pick WebSocket/LongPolling or supply a polyfill');
}

Type guard

const supportsSSE = (opts) => typeof (opts?.EventSource ?? (typeof globalThis !== 'undefined' ? globalThis.EventSource : undefined)) === 'function';

Try / catch

try {
  await connection.start();
} catch (e) {
  if (String(e.message).includes("'EventSource' is not supported")) {
    // fall back to WebSockets/LongPolling transport
  }
}

Prevention

When it happens

Trigger: Calling connection.start() (or negotiateMultipleTimes selecting SSE) where HttpTransportType.ServerSentEvents is negotiated and options.EventSource is null/undefined — e.g. in Node.js, web workers, or an environment where EventSource polyfill was not supplied.

Common situations: Running the signalr client in Node SSR or a web worker; IE/old browsers without EventSource; forgetting to pass an EventSource polyfill in withUrl options; forcing skipNegotiation with SSE transport in unsupported environments.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/68ec73795035d064. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore.Modules/OrchardCore.SignalR/wwwroot/Scripts/signalr.js:2998

                    }
                }
            }
        }
        if (transportExceptions.length > 0) {
            return Promise.reject(new AggregateErrors(`Unable to connect to the server with any of the available transports. ${transportExceptions.join(" ")}`, transportExceptions));
        }
        return Promise.reject(new Error("None of the transports supported by the client are supported by the server."));
    }
    _constructTransport(transport) {
        switch (transport) {
            case HttpTransportType.WebSockets:
                if (!this._options.WebSocket) {
                    throw new Error("'WebSocket' is not supported in your environment.");
                }
                return new WebSocketTransport(this._httpClient, this._accessTokenFactory, this._logger, this._options.logMessageContent, this._options.WebSocket, this._options.headers || {});
            case HttpTransportType.ServerSentEvents:
                if (!this._options.EventSource) {
                    throw new Error("'EventSource' is not supported in your environment.");
                }
                return new ServerSentEventsTransport(this._httpClient, this._httpClient._accessToken, this._logger, this._options);
            case HttpTransportType.LongPolling:
                return new LongPollingTransport(this._httpClient, this._logger, this._options);
            default:
                throw new Error(`Unknown transport: ${transport}.`);
        }
    }
    _startTransport(url, transferFormat) {
        this.transport.onreceive = this.onreceive;
        if (this.features.reconnect) {
            this.transport.onclose = async (e) => {
                let callStop = false;
                if (this.features.reconnect) {
                    try {
                        this.features.disconnected();
                        await this.transport.connect(url, transferFormat);
                        await this.features.resend();

View on GitHub (pinned to 4306c0717f)