RicoSuter/NSwag · error · InvalidOperationException

The template directory \

Error message

The template directory \"{CodeGenerators.OpenApiToCSharpClientCommand.TemplateDirectory}\" does not exist

What it means

The same template-directory validation as the TypeScript command, applied to OpenApiToCSharpClientCommand: after converting TemplateDirectory to an absolute path, a non-null value that does not exist on disk throws this InvalidOperationException.

Solutions

  1. Fix templateDirectory to an existing directory path.
  2. Use an absolute path or fix the working directory so the relative path resolves correctly.
  3. Delete the setting if custom templates are not needed.

Example fix

// before
"templateDirectory": "../templates/cs"
// after
"templateDirectory": "/build/repo/templates/cs"
Defensive patterns

Strategy: validation

Validate before calling

var td = doc.CodeGenerators?.OpenApiToCSharpClientCommand?.TemplateDirectory;
if (!string.IsNullOrEmpty(td) && !Directory.Exists(Path.GetFullPath(td, basePath)))
    throw new DirectoryNotFoundException($"Template directory not found: {td}");

Try / catch

try { var json = document.ToJsonWithRelativePaths(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("OpenApiToCSharpClientCommand") || (ex.Message.Contains("template directory") && ex.Message.Contains("does not exist")))
{ Console.Error.WriteLine($"Fix csharpClient templateDirectory: {ex.Message}"); throw; }

Prevention

When it happens

Trigger: CodeGenerators.OpenApiToCSharpClientCommand.TemplateDirectory is set (non-null) but Directory.Exists is false after path resolution — bad relative path, wrong base directory, deleted/moved directory.

Common situations: C# client customization templates referenced with paths relative to the machine where the document was created; running nswag.json from CI with a different working directory.

Related errors


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

Appendix: source

Thrown at src/NSwag.Commands/NSwagDocumentBase.cs:346

                CodeGenerators.OpenApiToTypeScriptClientCommand.TemplateDirectory = ConvertToAbsolutePath(
                    CodeGenerators.OpenApiToTypeScriptClientCommand.TemplateDirectory);

                if (CodeGenerators.OpenApiToTypeScriptClientCommand.TemplateDirectory != null && !Directory.Exists(CodeGenerators.OpenApiToTypeScriptClientCommand.TemplateDirectory))
                {
                    throw new InvalidOperationException($"The template directory \"{CodeGenerators.OpenApiToTypeScriptClientCommand.TemplateDirectory}\" does not exist");
                }
            }

            if (CodeGenerators.OpenApiToCSharpClientCommand != null)
            {
                CodeGenerators.OpenApiToCSharpClientCommand.ContractsOutputFilePath = ConvertToAbsolutePath(
                    CodeGenerators.OpenApiToCSharpClientCommand.ContractsOutputFilePath);
                CodeGenerators.OpenApiToCSharpClientCommand.TemplateDirectory = ConvertToAbsolutePath(
                    CodeGenerators.OpenApiToCSharpClientCommand.TemplateDirectory);

                if (CodeGenerators.OpenApiToCSharpClientCommand.TemplateDirectory != null && !Directory.Exists(CodeGenerators.OpenApiToCSharpClientCommand.TemplateDirectory))
                {
                    throw new InvalidOperationException($"The template directory \"{CodeGenerators.OpenApiToCSharpClientCommand.TemplateDirectory}\" does not exist");
                }
            }

            if (CodeGenerators.OpenApiToCSharpControllerCommand != null)
            {
                CodeGenerators.OpenApiToCSharpControllerCommand.TemplateDirectory = ConvertToAbsolutePath(
                    CodeGenerators.OpenApiToCSharpControllerCommand.TemplateDirectory);

                if (CodeGenerators.OpenApiToCSharpControllerCommand.TemplateDirectory != null && !Directory.Exists(CodeGenerators.OpenApiToCSharpControllerCommand.TemplateDirectory))
                {
                    throw new InvalidOperationException($"The template directory {CodeGenerators.OpenApiToCSharpControllerCommand.TemplateDirectory}\" does not exist");
                }
            }

            foreach (var generator in CodeGenerators.Items.Concat(SwaggerGenerators.Items))
            {
                generator.OutputFilePath = ConvertToAbsolutePath(generator.OutputFilePath);
            }

View on GitHub (pinned to 63daf8fcc3)