RicoSuter/NSwag · error · InvalidOperationException

No project (.csproj) file could be found under directory

Error message

No project (.csproj) file could be found under directory {path}.

What it means

ProjectMetadata.FindProject resolves the Project argument: a null path falls back to the current working directory, and a non-directory path is treated as the project file itself. If the given (or current) directory contains no *.csproj files, FindProject throws this error because NSwag cannot determine which project to build and inspect.

Solutions

  1. Pass the project file explicitly: `/project:path/to/MyApi.csproj`.
  2. Run nswag from the directory that directly contains the .csproj.
  3. For non-C# projects use the appropriate project file path — note FindProject only globs *.csproj, so pass the file path directly.
  4. Ensure you pass a project file, not a .sln, since solutions are not supported here.

Example fix

// before
nswag aspnetcore2openapi   (run from repo root, no csproj here)
// after
nswag aspnetcore2openapi /project:src/MyApi/MyApi.csproj
Defensive patterns

Strategy: validation

Validate before calling

var dir = projectArg ?? Directory.GetCurrentDirectory();
if (Directory.Exists(dir) && !Directory.EnumerateFiles(dir, "*.csproj").Any())
    throw new InvalidOperationException($"No .csproj directly under {dir}; pass /project: explicitly.");

Try / catch

try
{
    await command.RunAsync(processor, host);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("No project (.csproj) file could be found"))
{
    // retry with an explicit /project path
}

Prevention

When it happens

Trigger: Running `nswag aspnetcore2openapi` from a directory containing no .csproj (with no /project argument), or passing a directory path that has no .csproj directly inside it (the search is not recursive).

Common situations: Running nswag from a solution root or src/ folder one level above the project; project file uses a different extension (.vbproj, .fsproj) which the *.csproj glob misses; passing the solution file (.sln) instead of a project; typo'd project directory path.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at src/NSwag.Commands/Commands/Generation/AspNetCore/ProjectMetadata.cs:62

        public string TargetFileName { get; set; }
        public string TargetFrameworkIdentifier { get; set; }

        public static string FindProject(string path)
        {
            if (path == null)
            {
                path = Directory.GetCurrentDirectory();
            }
            else if (!Directory.Exists(path))
            {
                // It's not a directory. Treat the input path as the project file.
                return path;
            }

            var projectFiles = Directory.GetFiles(path, "*.csproj");
            if (projectFiles.Length == 0)
            {
                throw new InvalidOperationException($"No project (.csproj) file could be found under directory {path}.");
            }
            else if (projectFiles.Length > 1)
            {
                throw new InvalidOperationException($"More than one project was found in directory '{path}'. Specify one using its file name.");
            }

            return projectFiles[0];
        }

        public static async Task<ProjectMetadata> GetProjectMetadata(
            string file,
            string buildExtensionsDir,
            string framework,
            string configuration,
            string runtime,
            bool noBuild,
            string outputPath,
            IConsoleHost console = null)

View on GitHub (pinned to 63daf8fcc3)