RicoSuter/NSwag · error · InvalidOperationException

Multiple body parameters found in operation

Error message

Multiple body parameters found in operation '{_operation.OperationId}'.

What it means

OperationModelBase expects at most one OpenAPI body parameter per operation (per the Swagger/OpenAPI spec). While building the code-generation model, if a second body parameter is found it throws InvalidOperationException naming the operation.

Solutions

  1. Edit the OpenAPI/Swagger document so the operation has exactly one body parameter; merge the extras into the request schema.
  2. Fix the controller action: only one [FromBody] parameter per action (combine into a single request model).
  3. Regenerate the document instead of hand-editing the spec to keep it valid.

Example fix

// before
public IActionResult Save([FromBody] AddressDto address, [FromBody] ContactDto contact)
// after
public IActionResult Save([FromBody] SaveRequest request) // SaveRequest { AddressDto Address; ContactDto Contact; }
Defensive patterns

Strategy: validation

Validate before calling

foreach (var path in document.Paths)
  foreach (var op in path.Value.Values)
    if (op.Parameters.Count(p => p.Kind == NJsonSchema.OpenApiParameterKind.Body) > 1)
      throw new InvalidOperationException($"Operation '{op.OperationId}' has multiple body parameters");

Type guard

bool HasSingleBodyParameter(SwaggerOperationDescription op) => op.Parameters.Count(p => p.Kind == OpenApiParameterKind.Body) <= 1;

Try / catch

try { var code = generator.Generate(document); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Multiple body parameters")) { logger.LogError(ex, "Spec has an operation with more than one body parameter"); throw; }

Prevention

When it happens

Trigger: An operation's document/spec contains two parameters with Kind == Body, e.g. a handwritten JSON spec or NSwagDocument with two body parameters, or document generation misconfiguring an operation before code generation.

Common situations: Hand-edited swagger.json; older/post-processed specs; migrating from WCF/Swagger 1.2 definitions that allowed multiple body parts; code generators that added a body parameter alongside an existing [FromBody].

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of RicoSuter/NSwag@63daf8fcc3 (2026-09-14). Data as JSON: /api/errors/1e64f7fcc90359a5. Report an issue: GitHub.

Appendix: source

Thrown at src/NSwag.CodeGeneration/Models/OperationModelBase.cs:194

        /// <summary>Gets a value indicating whether the the request has a body.</summary>
        public bool HasBody => HasContent || HasFormParameters;

        /// <summary>Gets the content parameter.</summary>
        /// <exception cref="InvalidOperationException" accessor="get">Multiple body parameters found in operation.</exception>
        public TParameterModel ContentParameter
        {
            get
            {
                TParameterModel parameter = null;
                var parameters = Parameters;
                for (var i = 0; i < parameters.Count; i++)
                {
                    var p = parameters[i];
                    if (p.Kind == OpenApiParameterKind.Body)
                    {
                        if (parameter != null)
                        {
                            throw new InvalidOperationException($"Multiple body parameters found in operation '{_operation.OperationId}'.");
                        }

                        parameter = p;
                    }
                }

                return parameter;
            }
        }

        /// <summary>Gets the path parameters.</summary>
        public IEnumerable<TParameterModel> PathParameters => Parameters.Where(static p => p.Kind == OpenApiParameterKind.Path);

        /// <summary>Gets the query parameters.</summary>
        public IEnumerable<TParameterModel> QueryParameters => Parameters.Where(static p => p.Kind is OpenApiParameterKind.Query or OpenApiParameterKind.ModelBinding);

        /// <summary>Gets a value indicating whether the operation has query parameters.</summary>
        public bool HasQueryParameters => QueryParameters.Any();

View on GitHub (pinned to 63daf8fcc3)