microsoft/aspire · error · InvalidOperationException

Step ' ' is required by unknown step

Error message

Step '{step.Name}' is required by unknown step '{requiredBy}'

What it means

This is the mirror of the unknown-dependency check: ValidateSteps also verifies each name in a step's RequiredBySteps collection refers to an existing registered step. RequiredBySteps expresses 'this step must run before the named step'; pointing it at a step that does not exist breaks the ordering graph, so an InvalidOperationException is thrown.

Solutions

  1. Correct the RequiredBySteps entry to the exact Name of the registered step (ordinal comparison)
  2. Ensure the step that is supposed to require it is actually registered under the current execution context/pipeline
  3. Or invert the relationship: declare it as DependsOn on the other step, where the name is verified to exist
  4. Remove the stale RequiredBySteps entry if the ordering constraint no longer applies

Example fix

// before
step.RequiredBySteps.Add("publish-model");
// after (actual registered name)
step.RequiredBySteps.Add("publish");
Defensive patterns

Strategy: validation

Validate before calling

var registered = pipeline.Steps.Select(s => s.Name).ToHashSet(StringComparer.Ordinal);
foreach (var step in pipeline.Steps)
    foreach (var req in step.RequiredBySteps)
        if (!registered.Contains(req))
            throw new InvalidOperationException($"Step '{step.Name}' lists unknown requirer '{req}'");

Try / catch

try { await pipeline.ExecuteAsync(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("required by unknown step"))
{
    // ex.Message names the step and the unknown requirer; correct or remove the entry
}

Prevention

When it happens

Trigger: A step populates RequiredBySteps (or a helper like IsRequiredBy) with a name matching no registered step — typo, renamed/removed step, or a conditionally-registered requirer that did not get added in the current execution context.

Common situations: Symmetric wiring done from only one side: step A declares RequiredBy("B") but B's registration is behind a flag or feature check that is false; renaming step B without updating A; string-typed wiring across packages where one package changed its step names in a newer version.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting/Pipelines/DistributedApplicationPipeline.cs:835

            }
        }

        foreach (var step in steps)
        {
            foreach (var dependency in step.DependsOnSteps)
            {
                if (!stepNames.Contains(dependency))
                {
                    throw new InvalidOperationException(
                        $"Step '{step.Name}' depends on unknown step '{dependency}'");
                }
            }

            foreach (var requiredBy in step.RequiredBySteps)
            {
                if (!stepNames.Contains(requiredBy))
                {
                    throw new InvalidOperationException(
                        $"Step '{step.Name}' is required by unknown step '{requiredBy}'");
                }
            }
        }
    }

    /// <summary>
    /// Executes pipeline steps by building a Task DAG where each step waits on its dependencies.
    /// Failed steps prevent dependent steps from executing, while independent steps continue running.
    /// </summary>
    private static async Task ExecuteStepsAsTaskDag(
        List<PipelineStep> steps,
        Dictionary<string, PipelineStep> stepsByName,
        PipelineContext context)
    {
        // Validate no cycles exist in the dependency graph
        ValidateDependencyGraph(steps, stepsByName);

View on GitHub (pinned to 25830f84bd)