RicoSuter/NSwag · error · ArgumentException

The OpenAPI/Swagger document

Error message

The OpenAPI/Swagger document '{group.Key}' registered multiple times: Explicitly set the DocumentName property in NSwagServiceCollectionExtensions.AddSwaggerDocument() or NSwagServiceCollectionExtensions.AddOpenApiDocument().

What it means

OpenApiDocumentProvider groups all registered document configurations by DocumentName and throws ArgumentException if two or more share the same name, because the provider could not disambiguate which generator settings to use for a document request.

Solutions

  1. Set a unique DocumentName in each AddOpenApiDocument/AddSwaggerDocument call, e.g. c.DocumentName = "v2".
  2. Remove duplicate AddOpenApiDocument/AddSwaggerDocument registrations.
  3. Audit registered documents (for each Add call) to confirm names are unique.

Example fix

// before
services.AddOpenApiDocument();
services.AddOpenApiDocument(c => c.ApiGroupName = "v2");
// after
services.AddOpenApiDocument(c => c.DocumentName = "v1");
services.AddOpenApiDocument(c => c.DocumentName = "v2");
Defensive patterns

Strategy: validation

Validate before calling

var names = new List<string>();
void AddDoc(Action<AspNetCoreOpenApiDocumentGeneratorSettings> cfg) { var s = new AspNetCoreOpenApiDocumentGeneratorSettings(); cfg(s); if (names.Contains(s.DocumentName)) throw new ArgumentException($"Duplicate DocumentName '{s.DocumentName}'"); names.Add(s.DocumentName); }

Type guard

bool HasUniqueDocumentNames(IEnumerable<string> names) => names.GroupBy(n => n).All(g => g.Count() == 1);

Try / catch

try { app.UseOpenApi(); app.UseSwaggerUi(); }
catch (ArgumentException ex) when (ex.Message.Contains("registered multiple times")) { logger.LogError(ex, "Duplicate DocumentName registrations detected"); throw; }

Prevention

When it happens

Trigger: Calling services.AddOpenApiDocument()/AddSwaggerDocument() twice (or more) with the same (or default) DocumentName — the default DocumentName is 'v1', so two registrations without an explicit DocumentName collide.

Common situations: Registering documents for multiple API versions but forgetting to set DocumentName on each; duplicate AddOpenApiDocument calls left over after refactoring; two libraries both registering a default document.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at src/NSwag.AspNetCore/OpenApiDocumentProvider.cs:38

        public OpenApiDocumentProvider(IServiceProvider serviceProvider, IEnumerable<OpenApiDocumentRegistration> documents)
        {
            _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
            _documents = documents ?? throw new ArgumentNullException(nameof(documents));
        }

        public Task<OpenApiDocument> GenerateAsync(string documentName)
        {
            if (documentName == null)
            {
                throw new ArgumentNullException(nameof(documentName));
            }

            foreach (var group in _documents.GroupBy(g => g.DocumentName))
            {
                if (group.Count() > 1)
                {
                    throw new ArgumentException("The OpenAPI/Swagger document '" + group.Key + "' registered multiple times: " +
                        "Explicitly set the DocumentName property in " +
                        nameof(NSwagServiceCollectionExtensions.AddSwaggerDocument) + "() or " +
                        nameof(NSwagServiceCollectionExtensions.AddOpenApiDocument) + "().");
                }
            }

            var document = _documents.SingleOrDefault(g => g.DocumentName == documentName);
            if (document?.Settings == null)
            {
                throw new InvalidOperationException($"No registered OpenAPI/Swagger document found for the document name '{documentName}'. " +
                    $"Add with the AddSwagger()/AddOpenApi() methods in ConfigureServices().");
            }

            var generator = new AspNetCoreOpenApiDocumentGenerator(document?.Settings);
            return generator.GenerateAsync(_serviceProvider);
        }

        // Called by the <c>dotnet-getdocument</c> tool from the Microsoft.Extensions.ApiDescription.Server package.

View on GitHub (pinned to 63daf8fcc3)