RicoSuter/NSwag · error · InvalidOperationException

NSwag requires the assembly

Error message

NSwag requires the assembly {assembly.GetName()} to have either a BuildWebHost or CreateWebHostBuilder/CreateHostBuilder method. See https://docs.microsoft.com/en-us/aspnet/core/fundamentals/hosting?tabs=aspnetcore2x for suggestions on ways to refactor your startup type.

What it means

To generate an OpenAPI spec from a running ASP.NET Core app, NSwag must instantiate the app's IServiceProvider. GetServiceProvider looks for a BuildWebHost or CreateWebHostBuilder/CreateHostBuilder method on the given assembly; if none is found it throws InvalidOperationException. NSwag cannot construct the host for the target assembly.

Solutions

  1. Add a CreateHostBuilder or CreateWebHostBuilder static method the generator can call, or
  2. Upgrade NSwag — newer versions use HostFactoryResolver and support minimal hosting (WebApplication.CreateBuilder) directly.
  3. Use the /runtime /aspnetcore injection mode which builds the host inside the app process instead of reflecting on the assembly.
  4. Verify the /project and assembly arguments point at the assembly actually containing the host setup.

Example fix

// before (Program.cs, minimal hosting only)
var builder = WebApplication.CreateBuilder(args);
...

// after: expose a builder factory
public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(web => web.UseStartup<Startup>());
Defensive patterns

Strategy: try-catch

Validate before calling

// reflect before generating
var hasBuilder = typeof(Program).Assembly.GetTypes()
    .Any(t => t.GetMethod("CreateHostBuilder") != null || t.GetMethod("CreateWebHostBuilder") != null || t.GetMethods().Any(m => m.Name == "BuildWebHost"));
if (!hasBuilder) Console.Error.WriteLine("Assembly has no BuildWebHost/CreateHostBuilder entry point; use runtime mode or add one.");

Try / catch

try { GenerateFromAspNetCore(project); }
catch (InvalidOperationException ex) when (ex.Message.Contains("BuildWebHost or CreateWebHostBuilder")) { Console.Error.WriteLine("App lacks a host-builder factory method; add CreateHostBuilder or upgrade NSwag for minimal-hosting support."); }

Prevention

When it happens

Trigger: Running `nswag aspnetcore2openapi` (or /runtime /aspnetcore in an .nswag) against an assembly whose Program/Startup lacks any of BuildWebHost, CreateWebHostBuilder, or CreateHostBuilder entry points that NSwag can invoke.

Common situations: ASP.NET Core apps using WebApplication.CreateBuilder (minimal hosting, .NET 6+) where the pattern differs; custom Main that builds the host differently; target class path wrong so the wrong assembly is inspected; very old (1.x) hosting patterns.

Related errors


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

Appendix: source

Thrown at src/NSwag.Commands/HostApplication.cs:98

                        .CreateDefaultBuilder()
                        .UseStartup(startupType)
                        .Build()
                        .Services;
                    #else
                    serviceProvider = new HostBuilder()
                        .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup(startupType))
                        .Build()
                        .Services;
                    #endif
                }
            }

            if (serviceProvider != null)
            {
                return serviceProvider;
            }

            throw new InvalidOperationException($"NSwag requires the assembly {assembly.GetName()} to have " +
                                                $"either a BuildWebHost or CreateWebHostBuilder/CreateHostBuilder method. " +
                                                $"See https://docs.microsoft.com/en-us/aspnet/core/fundamentals/hosting?tabs=aspnetcore2x " +
                                                $"for suggestions on ways to refactor your startup type.");
        }

        internal static IServiceProvider GetServiceProviderWithHostFactoryResolver(Assembly assembly)
        {
#if NETFRAMEWORK
            return null;
#else
            // We're disabling the default server and the console host lifetime. This will disable:
            // 1. Listening on ports
            // 2. Logging to the console from the default host.
            // This is essentially what the test server does in order to get access to the application's
            // IServicerProvider *and* middleware pipeline.
            void ConfigureHostBuilder(object hostBuilder)
            {
                ((IHostBuilder)hostBuilder).ConfigureServices((context, services) =>

View on GitHub (pinned to 63daf8fcc3)