{"record":{"id":"ed9317e69085cea9","repo":"microsoft/aspire","slug":"step-step-name-depends-on-unknown-step-dependency","errorCode":null,"errorMessage":"Step '{step.Name}' depends on unknown step '{dependency}'","messagePattern":"Step '(.+?)' depends on unknown step '(.+?)'","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/Pipelines/DistributedApplicationPipeline.cs","lineNumber":826,"sourceCode":"    {\n        var stepNames = new HashSet<string>(StringComparer.Ordinal);\n\n        foreach (var step in steps)\n        {\n            if (!stepNames.Add(step.Name))\n            {\n                throw new InvalidOperationException(\n                    $\"Duplicate step name: '{step.Name}'\");\n            }\n        }\n\n        foreach (var step in steps)\n        {\n            foreach (var dependency in step.DependsOnSteps)\n            {\n                if (!stepNames.Contains(dependency))\n                {\n                    throw new InvalidOperationException(\n                        $\"Step '{step.Name}' depends on unknown step '{dependency}'\");\n                }\n            }\n\n            foreach (var requiredBy in step.RequiredBySteps)\n            {\n                if (!stepNames.Contains(requiredBy))\n                {\n                    throw new InvalidOperationException(\n                        $\"Step '{step.Name}' is required by unknown step '{requiredBy}'\");\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Executes pipeline steps by building a Task DAG where each step waits on its dependencies.\n    /// Failed steps prevent dependent steps from executing, while independent steps continue running.","sourceCodeStart":808,"sourceCodeEnd":844,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/Pipelines/DistributedApplicationPipeline.cs#L808-L844","documentation":"After collecting all step names, ValidateSteps verifies that every entry in a step's DependsOnSteps collection refers to a step that actually exists in the pipeline. A reference to a name that was never registered would make the dependency graph unschedulable, so an InvalidOperationException is thrown naming the depending step and the unknown dependency.","triggerScenarios":"A step calls DependsOn(\"SomeName\") (or populates DependsOnSteps) with a name that no registered step uses — typically a typo, a step that was removed/renamed, or a step belonging to a different pipeline. Also triggered when a step is conditionally registered but its dependents are registered unconditionally.","commonSituations":"Renaming a step without updating DependsOnSteps callers; upgrading an integration that renamed its internal step; misspelling the step name string; guard clauses (if (builder.ExecutionContext.IsRunMode)) that skip registering a step while other steps still depend on it.","solutions":["Fix the dependency string to exactly match an existing step's Name (names are compared Ordinally, so casing matters)","Register the missing step that the dependency refers to","Make the dependent step's registration conditional on the same condition that gates the dependency's registration","If a package renamed a step, update to the new step name per that package's docs"],"exampleFix":"// before\npipeline.AddStep(\"publish\").DependsOn(\"build-images\");\n// after (matching actual step name)\npipeline.AddStep(\"publish\").DependsOn(\"build-image\");","handlingStrategy":"validation","validationCode":"var registered = pipeline.Steps.Select(s => s.Name).ToHashSet(StringComparer.Ordinal);\nforeach (var step in pipeline.Steps)\n    foreach (var dep in step.DependsOnSteps)\n        if (!registered.Contains(dep))\n            throw new InvalidOperationException($\"Step '{step.Name}' references unknown dependency '{dep}'\");","typeGuard":null,"tryCatchPattern":"try { await pipeline.ExecuteAsync(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"depends on unknown step\"))\n{\n    // ex.Message names both the step and the unknown dependency; fix the string\n}","preventionTips":["Define step names as constants/shared fields so dependencies reference symbols, not raw strings","When renaming a step, grep for all DependsOn usages of the old name","Mirror registration conditions: gate dependent and dependency behind the same ExecutionContext check","Keep dependency wiring adjacent to the step registration it refers to"],"tags":["pipeline","dependency","validation","configuration"],"backgroundTag":"missing-dependency","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}