{"record":{"id":"c05fce80f9a5ee87","repo":"RicoSuter/NSwag","slug":"the-openapi-swagger-document-group-key-registered-multiple","errorCode":null,"errorMessage":"The OpenAPI/Swagger document '{group.Key}' registered multiple times: Explicitly set the DocumentName property in NSwagServiceCollectionExtensions.AddSwaggerDocument() or NSwagServiceCollectionExtensions.AddOpenApiDocument().","messagePattern":"The OpenAPI/Swagger document '(.+?)' registered multiple times: Explicitly set the DocumentName property in NSwagServiceCollectionExtensions\\.AddSwaggerDocument\\(\\) or NSwagServiceCollectionExtensions\\.AddOpenApiDocument\\(\\)\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/NSwag.AspNetCore/OpenApiDocumentProvider.cs","lineNumber":38,"sourceCode":"\n        public OpenApiDocumentProvider(IServiceProvider serviceProvider, IEnumerable<OpenApiDocumentRegistration> documents)\n        {\n            _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));\n            _documents = documents ?? throw new ArgumentNullException(nameof(documents));\n        }\n\n        public Task<OpenApiDocument> GenerateAsync(string documentName)\n        {\n            if (documentName == null)\n            {\n                throw new ArgumentNullException(nameof(documentName));\n            }\n\n            foreach (var group in _documents.GroupBy(g => g.DocumentName))\n            {\n                if (group.Count() > 1)\n                {\n                    throw new ArgumentException(\"The OpenAPI/Swagger document '\" + group.Key + \"' registered multiple times: \" +\n                        \"Explicitly set the DocumentName property in \" +\n                        nameof(NSwagServiceCollectionExtensions.AddSwaggerDocument) + \"() or \" +\n                        nameof(NSwagServiceCollectionExtensions.AddOpenApiDocument) + \"().\");\n                }\n            }\n\n            var document = _documents.SingleOrDefault(g => g.DocumentName == documentName);\n            if (document?.Settings == null)\n            {\n                throw new InvalidOperationException($\"No registered OpenAPI/Swagger document found for the document name '{documentName}'. \" +\n                    $\"Add with the AddSwagger()/AddOpenApi() methods in ConfigureServices().\");\n            }\n\n            var generator = new AspNetCoreOpenApiDocumentGenerator(document?.Settings);\n            return generator.GenerateAsync(_serviceProvider);\n        }\n\n        // Called by the <c>dotnet-getdocument</c> tool from the Microsoft.Extensions.ApiDescription.Server package.","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/RicoSuter/NSwag/blob/63daf8fcc3a25151b62eb4b326a1e8ea048a0d41/src/NSwag.AspNetCore/OpenApiDocumentProvider.cs#L20-L56","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set a unique DocumentName in each AddOpenApiDocument/AddSwaggerDocument call, e.g. c.DocumentName = \"v2\".","Remove duplicate AddOpenApiDocument/AddSwaggerDocument registrations.","Audit registered documents (for each Add call) to confirm names are unique."],"exampleFix":"// before\nservices.AddOpenApiDocument();\nservices.AddOpenApiDocument(c => c.ApiGroupName = \"v2\");\n// after\nservices.AddOpenApiDocument(c => c.DocumentName = \"v1\");\nservices.AddOpenApiDocument(c => c.DocumentName = \"v2\");","handlingStrategy":"validation","validationCode":"var names = new List<string>();\nvoid 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); }","typeGuard":"bool HasUniqueDocumentNames(IEnumerable<string> names) => names.GroupBy(n => n).All(g => g.Count() == 1);","tryCatchPattern":"try { app.UseOpenApi(); app.UseSwaggerUi(); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"registered multiple times\")) { logger.LogError(ex, \"Duplicate DocumentName registrations detected\"); throw; }","preventionTips":["Explicitly set DocumentName on every AddOpenApiDocument/AddSwaggerDocument call — never rely on the 'v1' default when registering more than one.","Keep all document registrations in one place for a quick uniqueness review.","Add a test asserting registered document names are unique."],"tags":["dependency-injection","configuration","duplicate-registration","nswag"],"backgroundTag":"file-already-exists","analyzedSha":"63daf8fcc3a25151b62eb4b326a1e8ea048a0d41","analyzedAt":"2026-09-14T11:38:15.205Z","contentChangedAt":"2026-09-14T11:38:15.205Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}