{"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/60108ba66eb7d1d12f595480091b4ad80a24b172/src/mono/browser/runtime/web-socket.ts#L19-L55","documentation":"Thrown by verifyEnvironment() in web-socket.ts when the runtime detects ENVIRONMENT_IS_SHELL - i.e. it is running in a bare JS shell (d8, V8/jsshell, js shell) rather than a browser or Node. JS shells do not provide a WebSocket implementation, so any attempt to create a WebSocket is blocked before construction.","triggerScenarios":"Calling ws_wasm_create (which calls verifyEnvironment) while dotnet Wasm is hosted in a JS shell such as d8 or the V8 shell. The first guard on line 36-38 throws before the WebSocket global is even inspected.","commonSituations":"Running automated tests or build scripts that load the Wasm runtime in a JS shell and then exercise networking; using the runtime under a REPL/shell for quick experiments; CI that uses a shell engine instead of Node or a browser.","solutions":["Run the networking code under Node (install the 'ws' package) or a real browser instead of a JS shell.","Skip/guard WebSocket-using code paths when ENVIRONMENT_IS_SHELL is true.","If you must use a shell, mock globalThis.WebSocket before the call - though note the shell guard fires first, so you would need to disable the shell path via a custom build."],"exampleFix":"// before - run in d8/jsshell\nws_wasm_create(uri, subProtocols, ptr); // throws\n// after - detect and skip\nif (!ENVIRONMENT_IS_SHELL) { ws_wasm_create(uri, subProtocols, ptr); }","handlingStrategy":"validation","validationCode":"import { ENVIRONMENT_IS_SHELL } from './globals';\nfunction canUseWebSocket(): boolean {\n  return !ENVIRONMENT_IS_SHELL && typeof globalThis.WebSocket === 'function';\n}\nif (canUseWebSocket()) { ws_wasm_create(uri, subProtocols, ptr); }","typeGuard":"function supportsWebSocket(): boolean {\n  return !ENVIRONMENT_IS_SHELL && typeof globalThis.WebSocket === 'function';\n}","tryCatchPattern":null,"preventionTips":["Gate networking code behind an environment check before invoking WebSocket APIs.","Prefer Node or a browser for integration tests that need WebSockets.","In Node, install the 'ws' package so the WebSocket global is present."],"tags":["websockets","environment","unsupported-platform","shell","network"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}