reactiveui/refit · error · InvalidOperationException

The response is unavailable for this API response.

Error message

The response is unavailable for this API response.

What it means

Thrown by ApiResponse<T>.ThrowsApiExceptionAsync when the response field is null — meaning no HTTP response was ever received (the call failed before getting a response, e.g. cancellation, DNS failure, or transport exception). There is no response to build an ApiException from, so the operation is invalid in that state.

Source

Thrown at src/Refit/ApiResponse{T}.cs:209

        {
            return;
        }

        response?.Dispose();
    }

    /// <summary>Throws the appropriate API exception for an unsuccessful response.</summary>
    /// <returns>A task that represents the asynchronous validation operation.</returns>
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    internal ValueTask<ApiResponse<T>> EnsureSlowAsync() => ThrowsApiExceptionAsync();

    /// <summary>Throws the appropriate API exception for an unsuccessful response.</summary>
    /// <returns>A task that represents the asynchronous throw operation.</returns>
    /// <exception cref="InvalidOperationException">No HTTP response was ever received, so there is nothing to build an API exception from.</exception>
    internal async ValueTask<ApiResponse<T>> ThrowsApiExceptionAsync()
    {
        var responseMessage = response
                              ?? throw new InvalidOperationException(
                                  "The response is unavailable for this API response.");

        var exception =
            Error
            ?? await ApiException
                .Create(
                    request,
                    request.Method,
                    responseMessage,
                    Settings)
                .ConfigureAwait(false);

        Dispose();

        throw exception;
    }
}

View on GitHub (pinned to b455f65ecc)

Solutions

  1. Check ApiResponse.Error / whether a response exists before forcing an ApiException; if Error is already set you may not need ThrowsApiExceptionAsync.
  2. Handle the transport/cancellation error separately (catch OperationCanceledException/HttpRequestException) rather than routing it through the ApiException path.
  3. For cancellation, verify the token before/around the call and treat a missing response as a non-HTTP failure.

Example fix

// before
var resp = await client.GetAsync(id);
await resp.EnsureSuccessAsync(); // throws if no response was received

// after — distinguish transport failure from HTTP error
if (resp.Error is OperationCanceledException) throw resp.Error;
if (!resp.IsSuccessStatusCode) await resp.EnsureSuccessAsync();
Defensive patterns

Strategy: try-catch

Validate before calling

// Distinguish 'no response' (transport/cancel) from 'got an error response'.
if (apiResponse.Error is OperationCanceledException or HttpRequestException)
    throw apiResponse.Error;
if (!apiResponse.IsSuccessStatusCode)
    await apiResponse.EnsureSuccessAsync();

Try / catch

try { await response.EnsureSuccessAsync(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("unavailable"))
{
    // No HTTP response was ever received — rethrow the underlying transport error.
    throw response.Error ?? ex;
}

Prevention

When it happens

Trigger: Calling EnsureSuccessStatusCode/EnsureSlowAsync on an ApiResponse<T> whose underlying response is null, which occurs when the pipeline captured an error (like an OperationCanceledException or HttpRequestException) without ever materializing an HttpResponseMessage. Typically reached when error-handling code assumes a response always exists.

Common situations: Cancellation (CancellationToken triggered) aborting the call before a response; transport-layer failures (DNS, connection refused, timeout) that never yield a response; wrapping ApiResponse and unconditionally calling the ensure method.

Related errors


AI-assisted analysis of reactiveui/refit@b455f65ecc (2026-08-13). Data as JSON: /api/errors/667f6af19e692ebc. Report an issue: GitHub.