SignalR/SignalR · error · ArgumentNullException

response

Error message

response

What it means

IResponseExtensions.ReadAsString throws ArgumentNullException('response') if the IResponse is null. It then opens the response stream and reads UTF-8 chunks, invoking the onChunk predicate for each. A null response indicates the upstream Get/Post never produced a response, which is itself a deeper bug — the guard prevents a NullReferenceException inside the stream reader.

Source

Thrown at src/Microsoft.AspNet.SignalR.Client/Http/IResponseExtensions.cs:18

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR.Client.Transports;
using Microsoft.AspNet.SignalR.Infrastructure;

namespace Microsoft.AspNet.SignalR.Client.Http
{
    public static class IResponseExtensions
    {
        public static Task<string> ReadAsString(this IResponse response, Func<ArraySegment<byte>, bool> onChunk)
        {
            if (response == null)
            {
                throw new ArgumentNullException("response");
            }

            var stream = response.GetStream();
            var reader = new AsyncStreamReader(stream);
            var result = new StringBuilder();
            var resultTcs = new DispatchingTaskCompletionSource<string>();

            reader.Data = buffer =>
            {
                if (onChunk(buffer))
                {
                    result.Append(Encoding.UTF8.GetString(buffer.Array, buffer.Offset, buffer.Count));
                }
            };

            reader.Closed = exception =>
            {
                response.Dispose();

View on GitHub (pinned to 693053b89a)

Solutions

  1. Only call ReadAsString on a response you have verified is non-null (from a successful Get/Post).
  2. Fix the upstream transport so it never returns null.
  3. In tests, supply a stub IResponse whose GetStream returns a readable stream.

Example fix

// before
var body = await response.ReadAsString(onChunk); // response null
// after
if (response == null) throw new InvalidOperationException("No response from transport");
var body = await response.ReadAsString(onChunk);
Defensive patterns

Strategy: validation

Validate before calling

if (response == null) throw new InvalidOperationException("transport returned no response");
var body = await response.ReadAsString(onChunk);

Type guard

static bool HasResponse(IResponse r) => r != null;

Prevention

When it happens

Trigger: Calling response.ReadAsString(onChunk) on a null IResponse; a custom transport returning null from Get/Post; test harness passing null.

Common situations: Custom transport implementation that does not return an IResponse; test double not set up; logic that discards a null response and still tries to read it.

Related errors


AI-assisted analysis of SignalR/SignalR@693053b89a (2026-08-13). Data as JSON: /api/errors/3605934f388e543f. Report an issue: GitHub.