RicoSuter/NSwag · error · InvalidOperationException
The method ' ' on path ' ' is registered multiple times for…
Error message
The method '{operation.Method}' on path '{path}' is registered multiple times for actions {string.Join(", ", conflictingApiDescriptions.Select(apiDesc => apiDesc.ActionDescriptor.DisplayName))}. What it means
NSwag's ASP.NET Core generator refuses to build the document when two API descriptions resolve to the same HTTP method and route path, because a single OpenAPI path item can only hold one operation per method. In AddOperationDescriptionsToDocument, after adding an operation it checks whether another action already produced the same (path, method) tuple and throws InvalidOperationException listing the conflicting action DisplayNames. This usually means two controller actions are indistinguishable by route.
Solutions
- Give each colliding action a distinct route template or HTTP method in its attribute routing (e.g. [HttpGet("{id:int}")] vs [HttpGet("active")]).
- Remove or merge the duplicate action that is not needed.
- Apply [ApiExplorerSettings(IgnoreApi = true)] to the action that should not appear in the document.
- Check the DisplayName values in the message to locate the exact conflicting controller actions and disambiguate their constraints (route constraints, HTTP method, accepted content type).
Example fix
// before
[HttpPost]
public IActionResult Create(OrderDto dto) { ... }
[HttpPost]
public IActionResult Update(OrderDto dto) { ... }
// after
[HttpPost("create")]
public IActionResult Create(OrderDto dto) { ... }
[HttpPost("update")]
public IActionResult Update(OrderDto dto) { ... } Defensive patterns
Strategy: validation
Validate before calling
// Before generating, scan API descriptions for (path, method) collisions
var collisions = apiDescriptions
.GroupBy(d => (d.RelativePath, d.HttpMethod.ToUpperInvariant()))
.Where(g => g.Count() > 1);
if (collisions.Any())
throw new InvalidOperationException("Duplicate route/method: " +
string.Join(", ", collisions.Select(g => g.Key))); Try / catch
try { var doc = await generator.GenerateAsync(settings); }
catch (InvalidOperationException ex) when (ex.Message.Contains("is registered multiple times"))
{
logger.LogError(ex, "Duplicate route registration in API actions");
} Prevention
- Give every action a unique (route template, HTTP method) pair; use route constraints to disambiguate.
- Run document generation in CI/tests so collisions fail the build early.
- Use [ApiExplorerSettings(IgnoreApi = true)] deliberately to exclude helper actions.
When it happens
Trigger: Calling GenerateControllers/UseHttpRepl-style document generation (AddOpenApiDocument/AddSwaggerDocument with an IApiDescriptionGroupCollectionProvider) when two actions map to the same path template and HTTP method, e.g. two [HttpPost("save")] actions in the same controller, or attribute routing that collapses two actions onto one route.
Common situations: Overloaded action methods without distinct [HttpGet("...")] templates; a route-template typo making two actions match; adding a new controller action that collides with an existing one; using conventional routing where DefaultUrlTemplate maps two actions to the same path; duplicated controllers registered with different namespaces but the same [Route].
Related errors
- The operation ' ' has more than one body parameter.
- NSwag requires the assembly
- The operation ' ' has more than one body parameter.
- The method ' ' on path ' ' is registered multiple times for…
- This UI does not support multiple documents per UI: Do not…
AI-assisted analysis of RicoSuter/NSwag@63daf8fcc3 (2026-09-14).
Data as JSON: /api/errors/76945480b863359b.
Report an issue: GitHub.
Appendix: source
Thrown at src/NSwag.Generation.AspNetCore/AspNetCoreOpenApiDocumentGenerator.cs:344
swaggerGenerator,
schemaResolver);
if (addOperation)
{
var path = operation.Path.Replace("//", "/");
if (!document.Paths.TryGetValue(path, out var pathItem))
{
document.Paths[path] = pathItem = [];
}
if (pathItem.ContainsKey(operation.Method))
{
var conflictingApiDescriptions = operations
.Where(t => t.Item1.Path == operation.Path && t.Item1.Method == operation.Method)
.Select(t => t.Item2)
.ToList();
throw new InvalidOperationException($"The method '{operation.Method}' on path '{path}' is registered multiple times for actions {string.Join(", ", conflictingApiDescriptions.Select(apiDesc => apiDesc.ActionDescriptor.DisplayName))}.");
}
pathItem[operation.Method] = operation.Operation;
addedOperations.Add(tuple);
}
}
return addedOperations;
}
private static void UpdateConsumesAndProduces(
OpenApiDocument document,
List<Tuple<OpenApiOperationDescription, ApiDescription, MethodInfo>> allOperations)
{
// TODO: Move to SwaggerGenerator class?
var documentConsumes = allOperations
.SelectMany(s => s.Item1.Operation.Consumes)View on GitHub (pinned to 63daf8fcc3)