{"record":{"id":"0daa5e7752f09137","repo":"microsoft/aspire","slug":"process-command-requires-a-non-empty-executable-path","errorCode":null,"errorMessage":"Process command requires a non-empty executable path.","messagePattern":"Process command requires a non-empty executable path\\.","errorType":"exception","errorClass":"DistributedApplicationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/ResourceBuilderExtensions.cs","lineNumber":3371,"sourceCode":"    {\n        return CreateProcessCommandSpec(new ProcessCommandSpecExportData\n        {\n            ExecutablePath = exportOptions.ExecutablePath,\n            Arguments = exportOptions.Arguments,\n            WorkingDirectory = exportOptions.WorkingDirectory,\n            EnvironmentVariables = exportOptions.EnvironmentVariables,\n            InheritEnvironmentVariables = exportOptions.InheritEnvironmentVariables,\n            StandardInputContent = exportOptions.StandardInputContent,\n            KillEntireProcessTree = exportOptions.KillEntireProcessTree\n        });\n    }\n\n    private static ProcessCommandSpec CreateProcessCommandSpec(ProcessCommandSpecExportData exportData)\n    {\n        var executablePath = exportData.ExecutablePath;\n        if (string.IsNullOrWhiteSpace(executablePath))\n        {\n            throw new DistributedApplicationException(\"Process command requires a non-empty executable path.\");\n        }\n\n        var arguments = exportData.Arguments ?? [];\n        foreach (var argument in arguments)\n        {\n            if (argument is null)\n            {\n                throw new DistributedApplicationException(\"Process command arguments cannot contain null values.\");\n            }\n        }\n\n        return new ProcessCommandSpec(executablePath)\n        {\n            WorkingDirectory = exportData.WorkingDirectory,\n            Arguments = arguments.ToArray(),\n            EnvironmentVariables = CreateEnvironmentVariables(exportData.EnvironmentVariables),\n            InheritEnvironmentVariables = exportData.InheritEnvironmentVariables ?? true,\n            StandardInputContent = exportData.StandardInputContent,","sourceCodeStart":3353,"sourceCodeEnd":3389,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/ResourceBuilderExtensions.cs#L3353-L3389","documentation":"CreateProcessCommandSpec converts exported ProcessCommandSpecExportData into a ProcessCommandSpec and requires a non-whitespace ExecutablePath, since the process runner needs a program to launch. A blank/empty path causes this DistributedApplicationException when the command is invoked.","triggerScenarios":"Register withProcessCommand with an ExecutablePath that is null, empty, or whitespace ('', '   '), or a createProcessSpec callback that returns export data with a missing ExecutablePath, then run the command.","commonSituations":"Config values for the executable not set (empty appsettings/env var); path built by joining segments where the base is null; polyglot hosts omitting the executablePath field; platform-specific binaries resolved to empty on the wrong OS.","solutions":["Provide a concrete executable path, e.g. new(\"dotnet\") or a resolved tool path.","Validate the path is non-whitespace in your factory before returning the spec.","Resolve platform-specific executables (e.g. 'dotnet' vs 'dotnet.exe', 'npm.cmd' on Windows) before registration or in the callback."],"exampleFix":"// before\nExecutablePath = config[\"CliToolPath\"] // empty when config missing\n// after\nvar toolPath = config[\"CliToolPath\"];\nif (string.IsNullOrWhiteSpace(toolPath))\n{\n    throw new InvalidOperationException(\"CliToolPath is not configured.\");\n}\nExecutablePath = toolPath;","handlingStrategy":"validation","validationCode":"if (string.IsNullOrWhiteSpace(exportData.ExecutablePath))\n    throw new InvalidOperationException(\"ExecutablePath must be a non-empty path before invoking the command.\");","typeGuard":"static bool HasExecutable(ProcessCommandSpecExportData? d) => d is { ExecutablePath: { } p } && !string.IsNullOrWhiteSpace(p);","tryCatchPattern":"try { await command(); }\ncatch (DistributedApplicationException ex) when (ex.Message.Contains(\"non-empty executable path\"))\n{ logger.LogError(ex, \"Process command has no executable configured\"); }","preventionTips":["Resolve platform-specific executable names before registration","Fail fast at startup if a configured tool path is missing","Never build paths by joining possibly-null segments; use Path.Combine with validated parts"],"tags":["process-command","empty-required-field","executable-path"],"backgroundTag":"empty-required-field","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}