reactiveui/refit · error · InvalidOperationException

BaseAddress must be set on the HttpClient instance

Error message

BaseAddress must be set on the HttpClient instance

What it means

ThrowIfBaseAddressMissing throws InvalidOperationException when HttpClient.BaseAddress is null, guarding the reflection/execution path that needs a base address to build relative requests. It is the shared helper equivalent of the base-address checks inside BuildRelativeUri.

Source

Thrown at src/Refit/RequestExecutionHelpers.cs:25

internal static partial class RequestExecutionHelpers
{
    /// <summary>The message used when content cannot be deserialized into the requested type.</summary>
    private const string DeserializationErrorMessage = "An error occured deserializing the response.";

    /// <summary>The error message used when the HTTP client has no base address configured.</summary>
    private const string BaseAddressRequiredMessage = "BaseAddress must be set on the HttpClient instance";

    /// <summary>Throws when a client cannot build relative generated requests.</summary>
    /// <param name="client">The HTTP client to inspect.</param>
    /// <exception cref="InvalidOperationException">Thrown when no base address is configured.</exception>
    internal static void ThrowIfBaseAddressMissing(HttpClient client)
    {
        if (client.BaseAddress is not null)
        {
            return;
        }

        throw new InvalidOperationException(BaseAddressRequiredMessage);
    }

    /// <summary>Builds the token a request runs against, applying a per-call timeout on top of the effective token.</summary>
    /// <param name="timeoutMilliseconds">The per-call timeout in milliseconds; values that are not positive disable it.</param>
    /// <param name="cancellationToken">The already-resolved effective cancellation token for the request.</param>
    /// <returns>The token the request should run against, and the timeout source to dispose once the request completes
    /// (null when no timeout was applied).</returns>
    internal static (CancellationToken Token, CancellationTokenSource? TimeoutSource) CreateTimeoutToken(
        int timeoutMilliseconds,
        CancellationToken cancellationToken)
    {
        if (timeoutMilliseconds <= 0)
        {
            return (cancellationToken, null);
        }

        var timeoutSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
        timeoutSource.CancelAfter(timeoutMilliseconds);

View on GitHub (pinned to b455f65ecc)

Solutions

  1. Set client.BaseAddress before use: client.BaseAddress = new Uri("https://api.example.com/")
  2. Prefer RestService.For<T>(hostUrl) or CreateHttpClient(hostUrl, settings) which set BaseAddress for you
  3. In DI, configure via services.AddRefitClient<T>().ConfigureHttpClient(c => c.BaseAddress = new Uri(...))
  4. Add a startup assertion that BaseAddress is non-null for clients handed to Refit

Example fix

// before
var client = new HttpClient();
var api = RestService.For<IHttpApi>(client);
await api.GetAsync(); // throws - base address missing

// after
var client = new HttpClient { BaseAddress = new Uri("https://api.example.com/") };
var api = RestService.For<IHttpApi>(client);
await api.GetAsync();
Defensive patterns

Strategy: validation

Validate before calling

if (client.BaseAddress is null)
    throw new InvalidOperationException(
        "HttpClient.BaseAddress must be set before creating a Refit client.");
var api = RestService.For<IHttpApi>(client);

Type guard

static bool HasBaseAddress(HttpClient client) => client.BaseAddress is not null;

Try / catch

try { await api.GetAsync(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("BaseAddress must be set"))
{
    // reconfigure the client with a BaseAddress and retry
}

Prevention

When it happens

Trigger: Any execution path that calls ThrowIfBaseAddressMissing on a client with no BaseAddress: generated or reflection runners that build and send relative requests without a configured host.

Common situations: DI-registered HttpClient without ConfigureHttpClient setting BaseAddress; manual new HttpClient() passed to the client factory; integration tests that forget the host; switching from a host-based RestService.For(hostUrl) overload to a client-based one without setting the address.

Related errors


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