reactiveui/refit · error · ArgumentException
Multipart requests may not contain a Body parameter
Error message
Multipart requests may not contain a Body parameter
What it means
Thrown by the body-resolution logic when a method is marked [Multipart] and one of its parameters also carries a [Body] attribute. A multipart request is by definition a collection of named parts (streams, files, objects) and cannot have a single serialized body; the two annotations are mutually exclusive, so Refit refuses to build the request.
Source
Thrown at src/Refit.Reflection/RestMethodInfoInternal.cs:616
/// than one parameter carries <see cref="BodyAttribute"/>.</exception>
internal Tuple<BodySerializationMethod, bool, int>? FindBodyParameter(
ParameterInfo[] parameterArray,
ParameterAttributeSet[] sets,
bool isMultipart,
HttpMethod method)
{
// The body parameter is found using the following logic / order of precedence:
// 1) [Body] attribute
// 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);View on GitHub (pinned to b455f65ecc)
Solutions
- Remove [Body] from the parameter — multipart parts are sent by passing objects/StreamPart without [Body].
- If you need to send a DTO inside multipart, pass it as an unannotated complex parameter (Refit serializes it as a part) or break the operation into a separate non-multipart JSON call.
- Keep [Multipart] only when you actually have multi-part content (files, streams); drop it if you only need a single JSON body.
Example fix
// before
[Post("/upload")]
[Multipart]
Task UploadAsync([Body] UploadRequest req, StreamPart file);
// after — the DTO becomes a multipart part, no [Body]
[Post("/upload")]
[Multipart]
Task UploadAsync(UploadRequest req, StreamPart file); Defensive patterns
Strategy: validation
Validate before calling
// Reject interface methods combining [Multipart] and a [Body] parameter.
foreach (var m in typeof(IMyApi).GetMethods())
{
var multipart = m.GetCustomAttribute<MultipartAttribute>() is not null;
var hasBody = m.GetParameters().Any(p => p.GetCustomAttribute<BodyAttribute>() is not null);
if (multipart && hasBody)
throw new InvalidOperationException($"{m.Name}: [Multipart] and [Body] are mutually exclusive.");
} Prevention
- Remember multipart requests are composed of parts — never annotate a part with [Body].
- When converting a JSON endpoint to upload, explicitly remove the [Body] attribute.
- Use a code-review/analyzed check that flags [Multipart]+[Body] co-occurrence.
When it happens
Trigger: An interface method with [Multipart] on the method AND [Body] on a parameter, e.g. `[Post("/upload")] [Multipart] Task UploadAsync([Body] MyDto dto, StreamPart file)`. The presence of both is the sole trigger.
Common situations: Migrating a JSON-body endpoint to a file-upload endpoint and forgetting to remove [Body]; attempting to send a DTO alongside a file inside a multipart form by annotating the DTO with [Body].
Related errors
- Only one parameter can be a Body parameter
- Multiple complex types found. Specify one parameter as the b
- Unexpected parameter type in a Multipart request. Parameter
- 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/f35dd307d3638737.
Report an issue: GitHub.