{"record":{"id":"7940420b033a5557","repo":"dotnet/runtime","slug":"websockets-are-not-supported-in-shell-js-engine-794042","errorCode":null,"errorMessage":"WebSockets are not supported in shell JS engine.","messagePattern":"WebSockets are not supported in shell JS engine\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/web-socket.ts","lineNumber":495,"sourceCode":"    type: number, // WebSocketMessageType\n    data: Uint8Array,\n    offset: number\n}\n\nfunction resolvedPromise(): Promise<void> | null {\n    // signal that we are finished synchronously\n    // this is optimization, which doesn't allocate and doesn't require to marshal resolve() call to C# side.\n    return null;\n}\n\nfunction rejectedPromise(message: string): Promise<any> | null {\n    const resolved = Promise.reject(new Error(message));\n    return wrapAsCancelable<void>(resolved);\n}\n\nfunction verifyEnvironment() {\n    if (ENVIRONMENT_IS_SHELL) {\n        throw new Error(\"WebSockets are not supported in shell JS engine.\");\n    }\n    if (typeof globalThis.WebSocket !== \"function\") {\n        const message = ENVIRONMENT_IS_NODE\n            ? \"Please install `ws` npm package to enable networking support.\"\n            : \"This browser doesn't support WebSocket API. Please use a modern browser. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms\";\n        throw new Error(message);\n    }\n}\n","sourceCodeStart":477,"sourceCodeEnd":504,"githubUrl":"https://github.com/dotnet/runtime/blob/290d5ab72cc1102813fbc0406fb186ceadabc340/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/web-socket.ts#L477-L504","documentation":"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.","triggerScenarios":"Running .NET WASM interop tests or scripts under d8/jsshell and invoking any WebSocket API (e.g. ClientWebSocket.ConnectAsync) on the C# side.","commonSituations":"Using the runtime's bundled shell harness for quick tests; CI scripts that default to a shell engine; reproducing a browser bug in d8.","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."],"exampleFix":"// before (runs in d8/jsshell)\nawait clientWebSocket.ConnectAsync(uri, cts.Token);\n\n// after\nif (typeof globalThis.WebSocket === 'function') {\n    await clientWebSocket.ConnectAsync(uri, cts.Token);\n}","handlingStrategy":"fallback","validationCode":"function canUseWebSocket(): boolean {\n    // ENVIRONMENT_IS_SHELL equivalent\n    const isShell = typeof (globalThis as any).process === \"undefined\" &&\n                    typeof (globalThis as any).importScripts === \"undefined\" &&\n                    typeof globalThis.WebSocket === \"undefined\";\n    return !isShell;\n}","typeGuard":"const supportsWebSocket = (): boolean =>\n    typeof globalThis.WebSocket === \"function\" ||\n    typeof (globalThis as any).require === \"function\";","tryCatchPattern":null,"preventionTips":["Run WebSocket-dependent code under Node or a browser, not d8/jsshell.","Gate WS features behind an environment check in test harnesses."],"tags":["websocket","environment","shell","network"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}