Skip to content

[Bug]: AddRefitGeneratedClient fails for methods with query parameters #2185

Description

@RoccoZero

Describe the bug 🐞

AddRefitGeneratedClient<T>() throws NotSupportedException at runtime when a generated Refit method contains query parameters.

Minimal interface:

public interface IAuthRestApi
{
    [Get("/signin")]
    Task<JsonNode> SignIn(
        [AliasAs("login")] string login,
        [AliasAs("password")] string password);
}

Registration:

[JsonSerializable(typeof(JsonNode))]
public partial class ApiJsonSerializerContext : JsonSerializerContext
{
}

var settings = new RefitSettings
{
    ContentSerializer = new SystemTextJsonContentSerializer(
        ApiJsonSerializerContext.Default.Options)
};

services
    .AddRefitGeneratedClient<IAuthRestApi>(settings)
    .ConfigureHttpClient(client =>
        client.BaseAddress = new Uri("https://api.example.com"));

Calling:

await api.SignIn("login", "password");

throws:

System.NotSupportedException: This Refit client was created with the generated-only API, but the generated client needs the reflection request builder for 'SignIn'. Enable generated request building for this method or use RestService.For when reflection is acceptable.
   at Refit.GeneratedOnlyRequestBuilder.BuildRestResultFuncForMethod(...)
   at Refit.Implementation.Generated.IAuthRestApi.SignIn(...)

The source generator creates IAuthRestApi.g.cs, but the generated SignIn implementation still uses the reflection-based path:

var refitFunc = refitRequestBuilder.BuildRestResultFuncForMethod(
    "SignIn",
    parameterTypes);

The same problem occurs when query parameters are explicitly included in the route:

[Get("/signin?login={login}&password={password}")]
Task<JsonNode> SignIn(string login, string password);

RefitGeneratedRequestBuilding is true, DisableRefitSourceGenerator is not enabled, and source-generated System.Text.Json metadata is provided for JsonNode.

A parameterless method returning the same JsonNode type is generated correctly through GeneratedRequestRunner.SendAsync, so the problem does not appear to be caused by JsonNode or JSON serialization. Other methods containing ordinary query parameters also fall back to BuildRestResultFuncForMethod.

Expected behavior: the source generator should generate request construction for ordinary route and query parameters so the interface can be used through AddRefitGeneratedClient<T>() in NativeAOT applications without reflection. If this method shape is intentionally unsupported, the analyzer should report a compile-time diagnostic explaining that the method is incompatible with generated-only registration instead of allowing registration and failing only at runtime.

Tested with:

  • Refit 12.1.0
  • Refit.HttpClientFactory 12.1.0
  • .NET 10
  • NativeAOT

Step to reproduce

Step to reproduce: See the complete reproduction steps in the bug description above.

Reproduction repository

https://github.com/reactiveui/refit

Expected behavior

See the expected behavior in the bug description above.

Screenshots 🖼️

No response

IDE

No response

Operating system

No response

Version

No response

Device

No response

Refit Version

No response

Additional information ℹ️

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Feature🐛 bug🔴 priority: highImportant: correctness, build, or AOT breakage on common paths🧬 area: source-genStub source generator, Roslyn, diagnostics, MSBuild integration

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions