microsoft/aspire · error · DistributedApplicationException

Could not get directory name of output path

Error message

Could not get directory name of output path

What it means

GetManifestRelativePath converts paths into paths relative to the manifest file's directory so published manifests reference portable relative locations. If Path.GetDirectoryName on the fully qualified manifest path returns null (no directory component, e.g. a root-level path), the context cannot compute relative paths and throws DistributedApplicationException.

Solutions

  1. Provide an --output-path that includes a real directory, e.g. './manifest.json' or './publish/manifest.json'.
  2. Avoid root-level or component-less paths for the manifest output.
  3. Verify the OutputPath value end-to-end in CI (getFullPath output) to catch platform mismatches.

Example fix

// before
--output-path /manifest.json
// after
--output-path ./publish/manifest.json
Defensive patterns

Strategy: validation

Validate before calling

var fullPath = Path.GetFullPath(outputPath);
if (string.IsNullOrEmpty(Path.GetDirectoryName(fullPath)))
{
    throw new ArgumentException($"Output path '{outputPath}' must include a directory component.");
}

Type guard

bool HasManifestDirectory(string manifestPath) =>
    Path.GetDirectoryName(Path.GetFullPath(manifestPath)) is { Length: > 0 };

Try / catch

try
{
    var relative = context.GetManifestRelativePath(path);
}
catch (DistributedApplicationException ex) when (ex.Message.Contains("directory name of output path"))
{
    logger.LogError(ex, "Manifest output path must include a valid directory.");
}

Prevention

When it happens

Trigger: Publishing with an --output-path whose full path has no parent directory component (e.g. a path at the filesystem root like '/manifest.json' or invalid drive-qualified forms), then writing any resource that requires a manifest-relative path (project files, build contexts, Dockerfile paths) via WriteToManifest or context writing.

Common situations: Passing a bare filename or root path as --output-path; platform-specific malformed paths (Windows drive paths on Linux); misconfigured OutputPath from environment/CI variables.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/1a5291ab39e28e02. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting/Publishing/ManifestPublishingContext.cs:70

    private readonly IPortAllocator _portAllocator = new PortAllocator();

    /// <summary>
    /// Generates a relative path based on the location of the manifest path.
    /// </summary>
    /// <param name="path">A path to a file.</param>
    /// <returns>The specified path as a relative path to the manifest.</returns>
    /// <exception cref="DistributedApplicationException">Throws when could not get the directory directory name from the output path.</exception>
    [return: NotNullIfNotNull(nameof(path))]
    public string? GetManifestRelativePath(string? path)
    {
        if (path is null)
        {
            return null;
        }

        var fullyQualifiedManifestPath = Path.GetFullPath(ManifestPath);
        var manifestDirectory = Path.GetDirectoryName(fullyQualifiedManifestPath) ?? throw new DistributedApplicationException("Could not get directory name of output path");

        var normalizedPath = path.Replace('\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar);
        var relativePath = Path.GetRelativePath(manifestDirectory, normalizedPath);

        return relativePath.Replace('\\', '/');
    }

    internal async Task WriteModel(DistributedApplicationModel model, CancellationToken cancellationToken)
    {
        _formattedParameters.Clear();
        _manifestResourceNames.Clear();

        foreach (var resource in model.Resources)
        {
            _manifestResourceNames.Add(resource.Name);
        }

        Writer.WriteStartObject();

View on GitHub (pinned to 25830f84bd)