{"record":{"id":"1a5291ab39e28e02","repo":"microsoft/aspire","slug":"could-not-get-directory-name-of-output-path","errorCode":null,"errorMessage":"Could not get directory name of output path","messagePattern":"Could not get directory name of output path","errorType":"exception","errorClass":"DistributedApplicationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/Publishing/ManifestPublishingContext.cs","lineNumber":70,"sourceCode":"\n    private readonly IPortAllocator _portAllocator = new PortAllocator();\n\n    /// <summary>\n    /// Generates a relative path based on the location of the manifest path.\n    /// </summary>\n    /// <param name=\"path\">A path to a file.</param>\n    /// <returns>The specified path as a relative path to the manifest.</returns>\n    /// <exception cref=\"DistributedApplicationException\">Throws when could not get the directory directory name from the output path.</exception>\n    [return: NotNullIfNotNull(nameof(path))]\n    public string? GetManifestRelativePath(string? path)\n    {\n        if (path is null)\n        {\n            return null;\n        }\n\n        var fullyQualifiedManifestPath = Path.GetFullPath(ManifestPath);\n        var manifestDirectory = Path.GetDirectoryName(fullyQualifiedManifestPath) ?? throw new DistributedApplicationException(\"Could not get directory name of output path\");\n\n        var normalizedPath = path.Replace('\\\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar);\n        var relativePath = Path.GetRelativePath(manifestDirectory, normalizedPath);\n\n        return relativePath.Replace('\\\\', '/');\n    }\n\n    internal async Task WriteModel(DistributedApplicationModel model, CancellationToken cancellationToken)\n    {\n        _formattedParameters.Clear();\n        _manifestResourceNames.Clear();\n\n        foreach (var resource in model.Resources)\n        {\n            _manifestResourceNames.Add(resource.Name);\n        }\n\n        Writer.WriteStartObject();","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/Publishing/ManifestPublishingContext.cs#L52-L88","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Provide an --output-path that includes a real directory, e.g. './manifest.json' or './publish/manifest.json'.","Avoid root-level or component-less paths for the manifest output.","Verify the OutputPath value end-to-end in CI (getFullPath output) to catch platform mismatches."],"exampleFix":"// before\n--output-path /manifest.json\n// after\n--output-path ./publish/manifest.json","handlingStrategy":"validation","validationCode":"var fullPath = Path.GetFullPath(outputPath);\nif (string.IsNullOrEmpty(Path.GetDirectoryName(fullPath)))\n{\n    throw new ArgumentException($\"Output path '{outputPath}' must include a directory component.\");\n}","typeGuard":"bool HasManifestDirectory(string manifestPath) =>\n    Path.GetDirectoryName(Path.GetFullPath(manifestPath)) is { Length: > 0 };","tryCatchPattern":"try\n{\n    var relative = context.GetManifestRelativePath(path);\n}\ncatch (DistributedApplicationException ex) when (ex.Message.Contains(\"directory name of output path\"))\n{\n    logger.LogError(ex, \"Manifest output path must include a valid directory.\");\n}","preventionTips":["Use a directory-qualified output path like ./publish/manifest.json.","Avoid root-level paths and bare filenames for --output-path.","Validate OutputPath in CI with Path.GetFullPath before publishing."],"tags":["publishing","manifest","path"],"backgroundTag":"directory-not-found","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}