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
- Keep a single [Body] parameter; combine the two objects into one DTO if both must be sent.
- Move the other parameter to [Query], [AliasAs], [Header], or make it a route parameter as appropriate.
- 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
- Keep exactly one [Body] per method; merge multiple objects into a single DTO.
- Use [Query]/[AliasAs]/[Header] to bind the other parameters explicitly.
- Add a build-time interface-validation test asserting the one-body rule.
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
- Multipart requests may not contain a Body parameter
- Multiple complex types found. Specify one parameter as the b
- URL path {relativePath} must not contain CR or LF characters
- Method "{methodInfo.Name}" is invalid. All REST Methods must
AI-assisted analysis of reactiveui/refit@b455f65ecc (2026-08-13).
Data as JSON: /api/errors/4becea101fa7a693.
Report an issue: GitHub.