RicoSuter/NSwag · error · InvalidOperationException

Process timed out.

Error message

Process {startInfo.FileName} timed out.

What it means

Exe.RunAsync starts a child process and waits for it to exit, racing it against a timeout (default 5 minutes when no explicit timeout is passed). If the process does not exit in time, the awaited delay wins and this error is thrown, indicating the generation (or metadata) process hung.

Solutions

  1. Ensure the ASP.NET Core app terminates after generation: use the NSwag-provided host builder pattern (CreateBuilder for generation) rather than unconditionally running the web host.
  2. Increase the timeout by invoking Exe.RunAsync with a larger TimeSpan if builds/starts are legitimately slow.
  3. Check for blocking startup code (sync DB calls, service discovery) and remove or shorten it.
  4. Guard any `app.Run()` call so it is skipped when running under the NSwag launcher/environment.

Example fix

// before (Program.cs)
var app = builder.Build();
app.Run(); // blocks forever during swagger generation
// after
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") != "Generation")
{
    app.Run();
}
Defensive patterns

Strategy: retry

Try / catch

try
{
    await Exe.RunAsync(exe, args, host, timeout: TimeSpan.FromMinutes(15));
}
catch (InvalidOperationException ex) when (ex.Message.Contains("timed out"))
{
    // log child output, kill orphaned process, optionally retry with a larger timeout
}

Prevention

When it happens

Trigger: Calling Exe.RunAsync (used for both `dotnet msbuild` metadata queries and the launcher process) where the process stays alive past `timeout ?? TimeSpan.FromSeconds(60 * 5)` — e.g. the ASP.NET app starts its web host and never terminates.

Common situations: The target app's Program.cs starts the Kestrel host and blocks instead of exiting after generation; a long build over the 5-minute default on slow CI machines; deadlock in app startup waiting on a database/network; app prompting for input on stdin.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at src/NSwag.Commands/Commands/Generation/AspNetCore/Exe.cs:64

#pragma warning disable CA2201
                    tcs.TrySetException(new Exception($"Process failed with non-zero exit code '{process.ExitCode}'."));
#pragma warning restore CA2201
                }
            };

            if (console != null)
            {
                process.OutputDataReceived += (_, eventArgs) => console.WriteMessage(eventArgs.Data + Environment.NewLine);
                process.ErrorDataReceived += (_, eventArgs) => console.WriteError(eventArgs.Data + Environment.NewLine);

                process.BeginErrorReadLine();
                process.BeginOutputReadLine();
            }

            var result = await Task.WhenAny(tcs.Task, Task.Delay(timeout ?? TimeSpan.FromSeconds(60 * 5))).ConfigureAwait(false);
            if (result != tcs.Task)
            {
                throw new InvalidOperationException($"Process {startInfo.FileName} timed out.");
            }
            else
            {
                console?.WriteMessage($"Done executing command. Exit Code: {process.ExitCode}.{Environment.NewLine}");
                return process.ExitCode;
            }
        }

        private static string ToArguments(IReadOnlyList<string> args)
        {
            var builder = new StringBuilder();
            for (var i = 0; i < args.Count; i++)
            {
                var argument = args[i];
                if (i != 0)
                {
                    builder.Append(' ');
                }

View on GitHub (pinned to 63daf8fcc3)