reactiveui/refit · error · InvalidOperationException

No request has been received yet.

Error message

No request has been received yet.

What it means

Thrown by StubHttp.LastRequestBodyAsync<T>() when you ask for the last received request body but the stub has captured zero requests. It is a test-helper guard ensuring you only inspect a body after a request has actually flowed through the stubbing HttpMessageHandler.

Source

Thrown at src/Refit.Testing/StubHttp.cs:222

        Justification = "The interface type is intentionally specified explicitly by the caller, matching RestService.ForGenerated<T>.")]
    public T CreateGeneratedClient<T>(string hostUrl, RefitSettings baseSettings) => RestService.ForGenerated<T>(hostUrl, ToSettings(baseSettings));

    /// <summary>Deserializes the body of the most recent request using the client's content serializer.</summary>
    /// <typeparam name="T">The type to deserialize the request body into.</typeparam>
    /// <returns>The deserialized request body, or <see langword="default"/> when the body is empty.</returns>
    /// <exception cref="InvalidOperationException">No request has been received yet.</exception>
    [SuppressMessage(
        "Design",
        "SST2307:Generic method type parameters should be inferable from the parameters",
        Justification = "The body type is intentionally specified explicitly by the caller, like a deserialization target.")]
    public Task<T?> LastRequestBodyAsync<T>()
    {
        CapturedBody? body;
        lock (_gate)
        {
            if (_bodies.Count == 0)
            {
                throw new InvalidOperationException("No request has been received yet.");
            }

            body = _bodies[^1];
        }

        return DeserializeBodyAsync<T>(body);
    }

    /// <summary>Deserializes the body of the request at <paramref name="index"/> using the client's content serializer.</summary>
    /// <typeparam name="T">The type to deserialize the request body into.</typeparam>
    /// <param name="index">The zero-based index into <see cref="Requests"/>.</param>
    /// <returns>The deserialized request body, or <see langword="default"/> when the body is empty.</returns>
    /// <exception cref="ArgumentOutOfRangeException">No request exists at <paramref name="index"/>.</exception>
    [SuppressMessage(
        "Design",
        "SST2307:Generic method type parameters should be inferable from the parameters",
        Justification = "The body type is intentionally specified explicitly by the caller, like a deserialization target.")]
    public Task<T?> RequestBodyAsync<T>(int index)

View on GitHub (pinned to b455f65ecc)

Solutions

  1. Ensure the client call that produces the body has been made and awaited before asserting.
  2. Guard the assertion: `if (stub.Requests.Count > 0) { var body = await stub.LastRequestBodyAsync<T>(); }`.
  3. Verify with stub.Requests.Count that a request was received before inspecting bodies.

Example fix

// before
var body = await stub.LastRequestBodyAsync<MyDto>(); // no request sent yet

// after
await client.CreateAsync(dto);
Assert.Equal(1, stub.Requests.Count);
var body = await stub.LastRequestBodyAsync<MyDto>();
Defensive patterns

Strategy: validation

Validate before calling

// Check a request was captured before reading its body.
if (stub.Requests.Count == 0)
{
    Assert.Fail("No request was sent through the stub.");
}
var body = await stub.LastRequestBodyAsync<MyDto>();

Prevention

When it happens

Trigger: Calling stub.LastRequestBodyAsync<T>() (or a sibling that reads _bodies) before any request has been sent through the stubbed client, or after only bodyless requests when no body was captured. The check is `_bodies.Count == 0` under a lock.

Common situations: Assertion ordering bug — calling the body assertion before invoking the client method; the SUT didn't actually issue the HTTP call (mocked out earlier); a GET request that has no body; forgetting to await the client call so the request never completed.

Related errors


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