{"record":{"id":"320d0fe463475a86","repo":"dotnet/runtime","slug":"please-install-ws-npm-package-to-enable-networki","errorCode":null,"errorMessage":"Please install `ws` npm package to enable networking support.","messagePattern":"Please install `ws` npm package to enable networking support\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/mono/browser/runtime/web-socket.ts","lineNumber":43,"sourceCode":"const 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}\n\nexport function ws_wasm_create (uri: string, sub_protocols: string[] | null, receive_status_ptr: VoidPtr): WebSocketExtension {\n    verifyEnvironment();\n    assert_js_interop();\n    mono_assert(uri && typeof uri === \"string\", () => `ERR12: Invalid uri ${typeof uri}`);\n    let ws: WebSocketExtension;","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/mono/browser/runtime/web-socket.ts#L25-L61","documentation":"Thrown by verifyEnvironment() inside ws_wasm_create() (src/mono/browser/runtime/web-socket.ts:35). The .NET WebAssembly runtime dispatches every System.Net.WebSockets call through ws_wasm_create; the guard first rejects shell engines, then checks typeof globalThis.WebSocket === 'function'. Under Node, the global WebSocket is absent from core, so the runtime refuses to create the socket and asks for the `ws` npm polyfill.","triggerScenarios":"Any managed WebSocket path (ClientWebSocket.ConnectAsync/ReceiveAsync, SignalR, WebSocket.SendAsync) while the runtime is hosted in Node (ENVIRONMENT_IS_NODE true), e.g. dotnet wasm test runner, prerender, or an SSR host. verifyEnvironment() runs at the very start of ws_wasm_create before new WebSocket(uri) is attempted.","commonSituations":"Running .NET wasm unit tests or prerender under Node without the optional networking dependency; upgrading the runtime to a version that began asserting the Node environment; calling a SignalR client from a Node-hosted wasm component.","solutions":["Run `npm install ws` in the host project; the runtime loader wires globalThis.WebSocket from the package when present.","If WebSockets are not needed in the Node run, remove the managed code path that calls ClientWebSocket / System.Net.WebSockets.","For a non-standard Node host, inject a WebSocket polyfill onto globalThis before dotnet.create()."],"exampleFix":"// before\nconst runtime = await dotnet.create();\n// managed code: new ClientWebSocket().ConnectAsync(...) -> Error: Please install `ws`...\n\n// after\n// package.json: \"dependencies\": { \"ws\": \"^8.x\" }\n// the runtime loader sets globalThis.WebSocket = ws when it detects Node\nconst runtime = await dotnet.create();","handlingStrategy":"validation","validationCode":"function nodeHasWebSocket(): boolean {\n  return !ENVIRONMENT_IS_NODE || typeof globalThis.WebSocket === 'function';\n}\nif (!nodeHasWebSocket()) {\n  // install `ws` (npm install ws) before booting the runtime\n}","typeGuard":"function supportsWebSocket(g: typeof globalThis): g is typeof globalThis & { WebSocket: typeof WebSocket } {\n  return typeof g.WebSocket === 'function';\n}","tryCatchPattern":null,"preventionTips":["Add `ws` to the host project's dependencies whenever the runtime may reach a WebSocket path under Node.","Feature-detect globalThis.WebSocket before booting the runtime in Node.","Keep WebSocket code out of Node-only prerender/SSR pipelines."],"tags":["network","node","websocket","dependencies"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}