microsoft/aspire · error · DistributedApplicationException

Process command ' ' environment variables require non-empty…

Error message

Process command '{processCommandSpec.ExecutablePath}' environment variables require non-empty names.

What it means

In the same pre-launch validation pass, CreateProcessSpec rejects environment variable entries with blank names in the final ProcessCommandSpec, throwing a DistributedApplicationException that names the executable. Blank names cannot be set on an OS process environment.

Solutions

  1. Guarantee all keys in EnvironmentVariables are non-empty, non-whitespace strings.
  2. Skip or rename blank keys when building the dictionary, failing loudly if the name is required.
  3. Fix upstream parsing/interpolation that produces empty names.

Example fix

// before
env[$"{prefix}_TOKEN"] = token; // prefix empty -> "_TOKEN"? no: "" when prefix null via interpolation of null
// after
if (!string.IsNullOrWhiteSpace(prefix))
{
    env[$"{prefix}_TOKEN"] = token;
}
Defensive patterns

Strategy: validation

Validate before calling

foreach (var k in processCommandSpec.EnvironmentVariables?.Keys ?? Enumerable.Empty<string>())
    if (string.IsNullOrWhiteSpace(k)) throw new InvalidOperationException($"Blank env name in spec for '{processCommandSpec.ExecutablePath}'.");

Type guard

static bool EnvValid(ProcessCommandSpec? s) => s?.EnvironmentVariables is null || s.EnvironmentVariables.Keys.All(k => !string.IsNullOrWhiteSpace(k));

Try / catch

try { await command(); }
catch (DistributedApplicationException ex) when (ex.Message.Contains("environment variables require non-empty names"))
{ logger.LogError(ex, "Blank env var name in spec for {Exe}", exePath); }

Prevention

When it happens

Trigger: Return a ProcessCommandSpec from a C# processSpecFactory whose EnvironmentVariables dictionary contains an empty/whitespace key, then run the command (this check runs on the C# callback route as well as export routes).

Common situations: Dictionary keys built from string interpolation or parsed config where the name collapses to empty; reusing a dictionary shared with other APIs that tolerated blank keys; deserialization filling empty keys.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting/ResourceBuilderExtensions.cs:3436

    }

    private static ProcessSpec CreateProcessSpec(ExecuteCommandContext context, ProcessCommandSpec processCommandSpec, ProcessCommandOptions commandOptions)
    {
        var arguments = processCommandSpec.Arguments ?? [];
        foreach (var argument in arguments)
        {
            if (argument is null)
            {
                throw new DistributedApplicationException($"Process command '{processCommandSpec.ExecutablePath}' arguments cannot contain null values.");
            }
        }

        var environmentVariables = processCommandSpec.EnvironmentVariables ?? new Dictionary<string, string>();
        foreach (var (name, value) in environmentVariables)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new DistributedApplicationException($"Process command '{processCommandSpec.ExecutablePath}' environment variables require non-empty names.");
            }

            if (value is null)
            {
                throw new DistributedApplicationException($"Process command '{processCommandSpec.ExecutablePath}' environment variable '{name}' requires a value.");
            }
        }

        return new ProcessSpec(processCommandSpec.ExecutablePath)
        {
            WorkingDirectory = processCommandSpec.WorkingDirectory,
            ArgumentList = arguments,
            EnvironmentVariables = environmentVariables,
            InheritEnv = processCommandSpec.InheritEnvironmentVariables,
            StandardInputContent = processCommandSpec.StandardInputContent,
            KillEntireProcessTree = processCommandSpec.KillEntireProcessTree,
            ThrowOnNonZeroReturnCode = false,
            ResolveExecutablePath = true,

View on GitHub (pinned to 25830f84bd)