dotnet/runtime · error · Error
WebSockets are not supported in shell JS engine.
Error message
WebSockets are not supported in shell JS engine.
What it means
Thrown by verifyEnvironment (web-socket.ts) when ENVIRONMENT_IS_SHELL is true, i.e. the code is running inside a JS shell (V8 d8, SpiderMonkey jsshell) rather than a browser or Node. WebSocket networking is unavailable in those shells, so the runtime refuses to proceed before any socket operation.
Source
Thrown at src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/web-socket.ts:495
type: number, // WebSocketMessageType
data: Uint8Array,
offset: number
}
function resolvedPromise(): Promise<void> | null {
// signal that we are finished synchronously
// this is optimization, which doesn't allocate and doesn't require to marshal resolve() call to C# side.
return null;
}
function rejectedPromise(message: string): Promise<any> | null {
const resolved = Promise.reject(new Error(message));
return wrapAsCancelable<void>(resolved);
}
function verifyEnvironment() {
if (ENVIRONMENT_IS_SHELL) {
throw new Error("WebSockets are not supported in shell JS engine.");
}
if (typeof globalThis.WebSocket !== "function") {
const message = ENVIRONMENT_IS_NODE
? "Please install `ws` npm package to enable networking support."
: "This browser doesn't support WebSocket API. Please use a modern browser. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms";
throw new Error(message);
}
}
View on GitHub (pinned to 290d5ab72c)
Solutions
- Run the same code under Node (with the `ws` package) or a real browser instead of a JS shell.
- Guard the WebSocket code path behind an environment check and skip it in shell engines.
- Use a mock/in-process transport for shell-based tests instead of real WebSockets.
Example fix
// before (runs in d8/jsshell)
await clientWebSocket.ConnectAsync(uri, cts.Token);
// after
if (typeof globalThis.WebSocket === 'function') {
await clientWebSocket.ConnectAsync(uri, cts.Token);
} Defensive patterns
Strategy: fallback
Validate before calling
function canUseWebSocket(): boolean {
// ENVIRONMENT_IS_SHELL equivalent
const isShell = typeof (globalThis as any).process === "undefined" &&
typeof (globalThis as any).importScripts === "undefined" &&
typeof globalThis.WebSocket === "undefined";
return !isShell;
} Type guard
const supportsWebSocket = (): boolean =>
typeof globalThis.WebSocket === "function" ||
typeof (globalThis as any).require === "function"; Prevention
- Run WebSocket-dependent code under Node or a browser, not d8/jsshell.
- Gate WS features behind an environment check in test harnesses.
When it happens
Trigger: Running .NET WASM interop tests or scripts under d8/jsshell and invoking any WebSocket API (e.g. ClientWebSocket.ConnectAsync) on the C# side.
Common situations: Using the runtime's bundled shell harness for quick tests; CI scripts that default to a shell engine; reproducing a browser bug in d8.
Related errors
- WebSockets are not supported in shell JS engine.
- Please install `ws` npm package to enable networking support
- This browser doesn't support WebSocket API. Please use a mod
- Please install `node-fetch` and `node-abort-controller` npm
- This browser doesn't support fetch API. Please use a modern
AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06).
Data as JSON: /api/errors/7940420b033a5557.
Report an issue: GitHub.