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

  1. Remove [Body] from the parameter — multipart parts are sent by passing objects/StreamPart without [Body].
  2. 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.
  3. 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

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


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