{"record":{"id":"082c049c07e21121","repo":"dotnet/runtime","slug":"websockets-are-not-supported-in-shell-js-engine","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/mono/browser/runtime/web-socket.ts","lineNumber":37,"sourceCode":"const wasm_ws_pending_send_buffer_type = Symbol.for(\"wasm ws_pending_send_buffer_type\");\nconst wasm_ws_pending_receive_event_queue = Symbol.for(\"wasm ws_pending_receive_event_queue\");\nconst wasm_ws_pending_receive_promise_queue = Symbol.for(\"wasm ws_pending_receive_promise_queue\");\nconst wasm_ws_pending_open_promise = Symbol.for(\"wasm ws_pending_open_promise\");\nconst wasm_ws_pending_open_promise_used = Symbol.for(\"wasm wasm_ws_pending_open_promise_used\");\nconst wasm_ws_pending_error = Symbol.for(\"wasm wasm_ws_pending_error\");\nconst wasm_ws_pending_close_promises = Symbol.for(\"wasm ws_pending_close_promises\");\nconst wasm_ws_pending_send_promises = Symbol.for(\"wasm ws_pending_send_promises\");\nconst wasm_ws_is_aborted = Symbol.for(\"wasm ws_is_aborted\");\nconst wasm_ws_close_sent = Symbol.for(\"wasm wasm_ws_close_sent\");\nconst wasm_ws_close_received = Symbol.for(\"wasm wasm_ws_close_received\");\nconst wasm_ws_receive_status_ptr = Symbol.for(\"wasm ws_receive_status_ptr\");\n\nconst ws_send_buffer_blocking_threshold = 65536;\nconst emptyBuffer = new Uint8Array();\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\nexport function ws_get_state (ws: WebSocketExtension): number {\n    if (ws.readyState != WebSocket.CLOSED)\n        return ws.readyState ?? -1;\n    const receive_event_queue = ws[wasm_ws_pending_receive_event_queue];\n    const queued_events_count = receive_event_queue.getLength();\n    if (queued_events_count == 0)\n        return ws.readyState ?? -1;\n    return ws[wasm_ws_close_sent] ? WebSocket.CLOSING : WebSocket.OPEN;\n}","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/dotnet/runtime/blob/290d5ab72cc1102813fbc0406fb186ceadabc340/src/mono/browser/runtime/web-socket.ts#L19-L55","documentation":"Thrown by verifyEnvironment when ENVIRONMENT_IS_SHELL is true, i.e. the runtime is executing under a non-browser, non-Node JS shell such as V8 d8, SpiderMonkey js, or JavaScriptCore. These shells have no networking stack, so any System.Net.WebSockets call (which routes through ws_wasm_create) is unsupported.","triggerScenarios":"Running the .NET WASM runtime under d8/js/jsc and invoking ClientWebSocket or any code path that calls ws_wasm_create.","commonSituations":"Executing wasm unit tests under raw d8; debugging the runtime via a JS shell; running browser-targeted code in a shell harness.","solutions":["Run the application in a real browser or Node.js instead of a JS shell.","Guard WebSocket usage behind an environment check and skip it (or stub it) in shell contexts.","For shell-based tests, mock the WebSocket interop layer or run the suite under Node with the ws package."],"exampleFix":"// before: unconditionally opening a WebSocket from .NET in a d8 test\nusing var ws = new ClientWebSocket();\nawait ws.ConnectAsync(uri, ct);\n// after: skip when running under a JS shell\nif (RuntimeInformation.IsOSPlatform(\"BROWSER\") && !IsInJsShell) { /* open ws */ }","handlingStrategy":"type-guard","validationCode":"// Skip WebSocket workloads under a JS shell\nconst isShell = typeof globalThis.navigator === 'undefined'\n  && typeof globalThis.WebSocket === 'undefined'\n  && typeof globalThis.process === 'undefined';\nif (isShell) {\n  console.warn('Skipping WebSocket test; unsupported in JS shell.');\n} else {\n  await openWebSocket();\n}","typeGuard":"function supportsNetworking(): boolean {\n  return typeof globalThis.WebSocket === 'function' || typeof globalThis.process !== 'undefined';\n}","tryCatchPattern":null,"preventionTips":["Run networked .NET WASM tests in a browser or Node, not d8/js/jsc.","Feature-detect the shell environment before any System.Net.WebSockets path.","Mock the WebSocket interop layer for shell-based unit tests."],"tags":["websocket","environment","shell","networking"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}