reactiveui/refit · error · ArgumentException

Only one parameter can be a Body parameter

Error message

Only one parameter can be a Body parameter

What it means

Thrown when more than one parameter on a method is explicitly annotated with [Body]. An HTTP request can carry exactly one body, so Refit cannot decide which to serialize as the payload and aborts at interface-analysis time.

Source

Thrown at src/Refit.Reflection/RestMethodInfoInternal.cs:625

        // 2) POST/PUT/PATCH: Reference type other than string
        // 3) If there are two reference types other than string, without the body attribute, throw
        var (bodyAttribute, bodyParameterIndex, hasMultipleBodyParameters) = FindBodyAttribute(sets);

        // multipart requests may not contain a body, implicit or explicit
        if (isMultipart)
        {
            if (bodyAttribute is not null)
            {
                throw new ArgumentException(
                    "Multipart requests may not contain a Body parameter");
            }

            return null;
        }

        if (hasMultipleBodyParameters)
        {
            throw new ArgumentException("Only one parameter can be a Body parameter");
        }

        // #1, body attribute wins
        if (bodyAttribute is not null)
        {
            return Tuple.Create(
                bodyAttribute.SerializationMethod,
                bodyAttribute.Buffered ?? RefitSettings.Buffered,
                bodyParameterIndex);
        }

        // Only post/put/patch carry an implicit body.
        return method.Equals(HttpMethod.Post)
            || method.Equals(HttpMethod.Put)
            || method.Equals(_patchMethod)
            ? FindImplicitBodyParameter(parameterArray, sets)
            : null;
    }

View on GitHub (pinned to b455f65ecc)

Solutions

  1. Keep a single [Body] parameter; combine the two objects into one DTO if both must be sent.
  2. Move the other parameter to [Query], [AliasAs], [Header], or make it a route parameter as appropriate.
  3. If you need nested data, redesign the body DTO to contain both rather than passing two bodies.

Example fix

// before
Task PostAsync([Body] Order order, [Body] Customer customer);

// after — combine into one body DTO, send the rest as query
public sealed record CreateOrderRequest(Order Order, Customer Customer);
Task PostAsync([Body] CreateOrderRequest body, [Query] string tenant);
Defensive patterns

Strategy: validation

Validate before calling

// Ensure at most one [Body] parameter per method.
foreach (var m in typeof(IMyApi).GetMethods())
{
    var bodyCount = m.GetParameters()
        .Count(p => p.GetCustomAttribute<BodyAttribute>() is not null);
    if (bodyCount > 1)
        throw new InvalidOperationException($"{m.Name} has {bodyCount} [Body] parameters; only one is allowed.");
}

Prevention

When it happens

Trigger: A method with two (or more) parameters each carrying [Body], e.g. `Task PostAsync([Body] A a, [Body] B b)`. FindBodyAttribute sets hasMultipleBodyParameters when it sees a second BodyAttribute, and the check fires before any serialization choice.

Common situations: Trying to merge two objects into one request body; refactoring a method and leaving a stale [Body]; misunderstanding that [Body] is exclusive.

Related errors


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