microsoft/aspire · error · DistributedApplicationException
Path to C# project could not be determined. The directory
Error message
Path to C# project could not be determined. The directory '{projectPath}' must contain a single .csproj file. What it means
AddCSharpApp throws DistributedApplicationException when the supplied project path is not a .csproj or .cs file and, if it is a directory, that directory does not contain exactly one .csproj file. The message distinguishes two cases: the path exists as a directory without a single .csproj, or the path is otherwise invalid (not a .cs/.csproj file or usable directory). Aspire cannot determine which project to run, so it fails during resource callback validation.
Solutions
- Pass the full path to the specific .csproj (or the .cs entry file) directly.
- If passing a directory, ensure it contains exactly one .csproj file; move or exclude extra project files.
- Fix path typos and verify the path exists relative to the AppHost's working directory.
- Move shared class libraries out of the target directory or reference them explicitly instead.
Example fix
// before
builder.AddCSharpApp("frontend", "../frontend"); // directory has 2 .csproj files
// after
builder.AddCSharpApp("frontend", "../frontend/Frontend.csproj"); Defensive patterns
Strategy: validation
Validate before calling
var resolved = Path.GetFullPath(projectPath);
if (!resolved.EndsWith(".csproj", StringComparison.OrdinalIgnoreCase) &&
!resolved.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) &&
Directory.EnumerateFiles(resolved, "*.csproj").Take(2).Count() != 1)
{
throw new DistributedApplicationException($"'{projectPath}' must be a .csproj, a .cs file, or a directory with exactly one .csproj.");
} Try / catch
try
{
builder.AddCSharpApp(name, projectPath);
}
catch (DistributedApplicationException ex) when (ex.Message.Contains("Path to C# project could not be determined"))
{
logger.LogError(ex, "Project path '{Path}' does not resolve to a single .csproj.", projectPath);
} Prevention
- Always point AddCSharpApp at the .csproj file itself.
- Ensure target directories contain exactly one .csproj.
- Use paths relative to the AppHost project and verify them in a smoke test.
When it happens
Trigger: Calling builder.AddCSharpApp("name", path) with a directory containing zero or multiple .csproj files; or with a path not ending in .csproj/.cs that is not a directory; or a mistyped path.
Common situations: Pointing at a solution folder or multi-project directory, typos in the path, passing a directory that holds several projects, or using a relative path that resolves differently from the AppHost working directory.
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
- Aspire skills bundle contains an empty relative path.
- Aspire skills bundle path
- Launch profile must be a string or ProjectResourceOptions.
- Path must start with '/'.
- Project defaults have already been applied to resource
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/e719a294cefa738f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting/ProjectResourceBuilderExtensions.cs:434
path = PathNormalizer.NormalizePathForCurrentPlatform(Path.Combine(builder.AppHostDirectory, path));
var projectMetadata = new ProjectMetadata(path);
var resource = builder.AddResource(app)
.WithAnnotation(projectMetadata)
.WithProjectDefaults(options);
resource.OnBeforeResourceStarted((r, e, ct) =>
{
var projectPath = projectMetadata.ProjectPath;
// Validate project path
if (!projectPath.EndsWith(".csproj", StringComparison.OrdinalIgnoreCase) && !projectPath.EndsWith(".cs", StringComparison.OrdinalIgnoreCase))
{
// Project path did not resolve to a .csproj or .cs file
var message = Directory.Exists(projectPath)
? $"Path to C# project could not be determined. The directory '{projectPath}' must contain a single .csproj file."
: $"The C# app path '{projectPath}' is invalid. The path must be to a .cs file, .csproj file, or directory containing a single .csproj file.";
throw new DistributedApplicationException(message);
}
return Task.CompletedTask;
});
return resource;
}
private static void ApplyProjectResourceOptions(ProjectResourceOptions target, ProjectResourceOptions source)
{
ArgumentNullException.ThrowIfNull(target);
ArgumentNullException.ThrowIfNull(source);
target.LaunchProfileName = source.LaunchProfileName;
target.ExcludeLaunchProfile = source.ExcludeLaunchProfile;
target.ExcludeKestrelEndpoints = source.ExcludeKestrelEndpoints;
}
View on GitHub (pinned to 25830f84bd)