{"record":{"id":"289abd753c72f0ad","repo":"SignalR/SignalR","slug":"httpclient-289abd","errorCode":null,"errorMessage":"httpClient","messagePattern":"httpClient","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.AspNet.SignalR.Client/Transports/TransportHelper.cs","lineNumber":21,"sourceCode":"\nusing System;\nusing System.Globalization;\nusing System.Threading.Tasks;\nusing Microsoft.AspNet.SignalR.Client.Http;\nusing Microsoft.AspNet.SignalR.Client.Infrastructure;\nusing Newtonsoft.Json;\nusing Newtonsoft.Json.Linq;\n\nnamespace Microsoft.AspNet.SignalR.Client.Transports\n{\n    public class TransportHelper\n    {\n        // virtual to allow mocking\n        public virtual Task<NegotiationResponse> GetNegotiationResponse(IHttpClient httpClient, IConnection connection, string connectionData)\n        {\n            if (httpClient == null)\n            {\n                throw new ArgumentNullException(\"httpClient\");\n            }\n\n            if (connection == null)\n            {\n                throw new ArgumentNullException(\"connection\");\n            }\n\n            var negotiateUrl = UrlBuilder.BuildNegotiate(connection, connectionData);\n\n            httpClient.Initialize(connection);\n\n            return httpClient.Get(negotiateUrl, connection.PrepareRequest, isLongRunning: false)\n                            .Then(response => response.ReadAsString())\n                            .Then(raw =>\n                            {\n                                if (String.IsNullOrEmpty(raw))\n                                {\n                                    throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.Error_ServerNegotiationFailed));","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/SignalR/SignalR/blob/693053b89a9e1f5ce819e3233ed159a6409de22b/src/Microsoft.AspNet.SignalR.Client/Transports/TransportHelper.cs#L3-L39","documentation":"Thrown by TransportHelper.GetNegotiationResponse when 'httpClient' is null. Negotiation issues an HTTP GET to the /negotiate endpoint and needs the IHttpClient to perform it.","triggerScenarios":"Calling GetNegotiationResponse(null, connection, connectionData) — usually from a custom transport or test stubbing TransportHelper.","commonSituations":"Mocking TransportHelper / GetNegotiationResponse in tests and passing null; DI misconfiguration of the HttpClient dependency.","solutions":["Pass the same IHttpClient the transport holds (DefaultHttpClient or an injected non-null mock).","Prefer ClientTransportBase.Negotiate(...) which forwards its own HttpClient to the helper.","Null-check httpClient at the orchestration layer before delegating."],"exampleFix":"// before\n_transportHelper.GetNegotiationResponse(null, connection, connectionData);\n\n// after\n_transportHelper.GetNegotiationResponse(httpClient, connection, connectionData);","handlingStrategy":"validation","validationCode":"if (httpClient == null) throw new ArgumentNullException(nameof(httpClient));","typeGuard":"static bool HasHttpClient(IHttpClient c) => c != null;","tryCatchPattern":null,"preventionTips":["Pass the transport's HttpClient to negotiation helpers; do not stub with null.","Use ClientTransportBase.Negotiate(...) which forwards its own HttpClient.","Ensure DI/test mocks return a non-null IHttpClient."],"tags":["csharp","signalr","null-argument","validation","transport","http","negotiation"],"backgroundTag":null,"analyzedSha":"693053b89a9e1f5ce819e3233ed159a6409de22b","analyzedAt":"2026-08-13T22:23:59.793Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}