microsoft/aspire · error · InvalidOperationException

Unix detached process launch requires a DCP executable path.

Error message

Unix detached process launch requires a DCP executable path.

What it means

On Unix, IsolatedProcess's detached start mode forks the process through the DCP (Developer Control Plane) executable, which must be supplied via DetachedUnixLauncherPath on the start info. StartDetachedUnixAsync throws InvalidOperationException when that path is null because a detached launch cannot proceed without the launcher.

Solutions

  1. Ensure the DCP executable exists and is resolved (check the Aspire CLI installation / DOTNET ASPIRE defaults) before starting detached.
  2. Set DetachedUnixLauncherPath explicitly on IsolatedProcessStartInfo when constructing it manually.
  3. Reinstall or update the Aspire CLI so the DCP binaries are present.
  4. Run in non-detached mode if DCP is unavailable, so the process is launched directly.

Example fix

// before
var startInfo = new IsolatedProcessStartInfo { Detached = true }; // no launcher path
// after
var startInfo = new IsolatedProcessStartInfo
{
    Detached = true,
    DetachedUnixLauncherPath = dcpPath // resolved from DcpLocator
};
Defensive patterns

Strategy: type-guard

Validate before calling

if (startInfo.Detached && startInfo.DetachedUnixLauncherPath is null)
    throw new InvalidOperationException("Detached start on Unix requires DetachedUnixLauncherPath.");

Type guard

bool CanStartDetached(IsolatedProcessStartInfo info) =>
    !info.Detached || info.DetachedUnixLauncherPath is not null;

Try / catch

try
{
    await process.StartAsync(ct);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("DCP executable path"))
{
    // resolve DCP path and retry, or fall back to non-detached start
}

Prevention

When it happens

Trigger: Calling IsolatedProcess.StartAsync with Detached = true (or equivalent detached start info) on Unix while startInfo.DetachedUnixLauncherPath was never set, typically because the DCP path wasn't resolved from the CLI's DCP locator.

Common situations: A dev environment where DCP was not built/downloaded; the CLI's DCP resolution failed silently and returned null; manually constructing IsolatedProcessStartInfo without setting the launcher path.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Cli/Processes/IsolatedProcess.Unix.cs:17

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using System.Globalization;

namespace Aspire.Cli.Processes;

internal sealed partial class IsolatedProcess
{
    private static async Task<StartedProcess> StartDetachedUnixAsync(
        IsolatedProcessStartInfo startInfo,
        CancellationToken cancellationToken)
    {
        if (startInfo.DetachedUnixLauncherPath is null)
        {
            throw new InvalidOperationException("Unix detached process launch requires a DCP executable path.");
        }

        var dcpStartInfo = new ProcessStartInfo
        {
            FileName = startInfo.DetachedUnixLauncherPath,
            UseShellExecute = false,
            CreateNoWindow = true,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            RedirectStandardInput = false,
            WorkingDirectory = startInfo.WorkingDirectory
        };

        dcpStartInfo.ArgumentList.Add("fork-process");
        dcpStartInfo.ArgumentList.Add("--monitor");
        dcpStartInfo.ArgumentList.Add(Environment.ProcessId.ToString(CultureInfo.InvariantCulture));
        dcpStartInfo.ArgumentList.Add("--monitor-identity-time");
        dcpStartInfo.ArgumentList.Add(ProcessTreeGracefulShutdownService.FormatDcpProcessStartTime(GetCurrentProcessDcpMonitorStartTime()));

View on GitHub (pinned to 25830f84bd)