{"record":{"id":"c4d40635912959e1","repo":"OrchardCMS/OrchardCore","slug":"no-usable-httpclient-found","errorCode":null,"errorMessage":"No usable HttpClient found.","messagePattern":"No usable HttpClient found\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/OrchardCore.Modules/OrchardCore.SignalR/wwwroot/Scripts/signalr.js","lineNumber":816,"sourceCode":"// The .NET Foundation licenses this file to you under the MIT license.\n\n\n\n\n\n/** Default implementation of {@link @microsoft/signalr.HttpClient}. */\nclass DefaultHttpClient extends HttpClient {\n    /** Creates a new instance of the {@link @microsoft/signalr.DefaultHttpClient}, using the provided {@link @microsoft/signalr.ILogger} to log messages. */\n    constructor(logger) {\n        super();\n        if (typeof fetch !== \"undefined\" || Platform.isNode) {\n            this._httpClient = new FetchHttpClient(logger);\n        }\n        else if (typeof XMLHttpRequest !== \"undefined\") {\n            this._httpClient = new XhrHttpClient(logger);\n        }\n        else {\n            throw new Error(\"No usable HttpClient found.\");\n        }\n    }\n    /** @inheritDoc */\n    send(request) {\n        // Check that abort was not signaled before calling send\n        if (request.abortSignal && request.abortSignal.aborted) {\n            return Promise.reject(new AbortError());\n        }\n        if (!request.method) {\n            return Promise.reject(new Error(\"No method defined.\"));\n        }\n        if (!request.url) {\n            return Promise.reject(new Error(\"No url defined.\"));\n        }\n        return this._httpClient.send(request);\n    }\n    getCookieString(url) {\n        return this._httpClient.getCookieString(url);","sourceCodeStart":798,"sourceCodeEnd":834,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore.Modules/OrchardCore.SignalR/wwwroot/Scripts/signalr.js#L798-L834","documentation":"HttpConnection's constructor throws 'No usable HttpClient found.' when neither the WHATWG fetch API (fetch/AbortController) nor XMLHttpRequest is available in the runtime. The SignalR client needs at least one of these to perform HTTP requests, and it fails at connection construction rather than at first send.","triggerScenarios":"Running the browser build of signalr.js in Node.js without a fetch polyfill; very old browsers lacking both fetch and XHR; restricted environments (web workers/SSR) where globals are stripped.","commonSituations":"Server-side rendering importing the browser bundle; Jest/jsdom tests with outdated environment flags; embedding the client in a sandboxed worker without network globals.","solutions":["Install a fetch polyfill (e.g. whatwg-fetch, node-fetch assigned to globalThis) before importing/using the client","In Node, import '@microsoft/signalr' (the Node build) instead of the browser 'signalr.js' bundle","Ensure the test/SSR environment provides fetch or XMLHttpRequest globals","Target a browser that supports fetch (or supply XHR fallback)"],"exampleFix":"// before (Node, browser bundle)\nimport { HubConnectionBuilder } from './wwwroot/Scripts/signalr.js';\n// after\nimport * as signalr from '@microsoft/signalr'; // Node-compatible entry\nif (!globalThis.fetch) globalThis.fetch = (await import('node-fetch')).default;","handlingStrategy":"fallback","validationCode":"if (typeof fetch === 'undefined' && typeof XMLHttpRequest === 'undefined') throw new Error('SignalR requires fetch or XMLHttpRequest polyfill');","typeGuard":"const hasHttpStack = () => typeof globalThis.fetch !== 'undefined' || typeof globalThis.XMLHttpRequest !== 'undefined';","tryCatchPattern":"try { connection = new HubConnectionBuilder().withUrl(url).build(); } catch (e) { if (e.message === 'No usable HttpClient found.') installPolyfill(); }","preventionTips":["Import the Node entry (@microsoft/signalr) outside browsers","Polyfill fetch for SSR/tests/workers before importing the client","Lint against importing the browser bundle in server code"],"tags":["environment","polyfill","signalr","node"],"backgroundTag":"unsupported-platform","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}