{"record":{"id":"64f75f78ba47a95a","repo":"microsoft/aspire","slug":"step-stepname-not-found-in-pipeline-available-steps","errorCode":null,"errorMessage":"Step '{stepName}' not found in pipeline. Available steps: {availableSteps}","messagePattern":"Step '(.+?)' not found in pipeline\\. Available steps: (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/Pipelines/DistributedApplicationPipeline.cs","lineNumber":608,"sourceCode":"    /// <param name=\"context\">The pipeline context for execution.</param>\n    /// <returns>A task representing the asynchronous operation.</returns>\n    internal async Task ExecuteStepSequentiallyAsync(\n        string stepName,\n        PipelineContext context)\n    {\n        var allSteps = await ResolveStepsAsync(context).ConfigureAwait(false);\n\n        if (allSteps.Count == 0)\n        {\n            return;\n        }\n\n        var allStepsByName = allSteps.ToDictionary(s => s.Name, StringComparer.Ordinal);\n\n        if (!allStepsByName.TryGetValue(stepName, out var targetStep))\n        {\n            var availableSteps = string.Join(\", \", allSteps.Select(s => $\"'{s.Name}'\"));\n            throw new InvalidOperationException(\n                $\"Step '{stepName}' not found in pipeline. Available steps: {availableSteps}\");\n        }\n\n        var stepsToExecute = ComputeTransitiveDependencies(targetStep, allStepsByName);\n\n        await ExecuteStepsSequentially(stepsToExecute, context).ConfigureAwait(false);\n    }\n\n    /// <summary>\n    /// Resolves all pipeline steps (from built-in steps and resource annotations),\n    /// normalizes RequiredBy relationships to DependsOn, and validates the steps\n    /// without executing them. The returned list is in collection order; use\n    /// <see cref=\"GetTopologicalOrder\"/> to obtain execution order.\n    /// </summary>\n    internal async Task<List<PipelineStep>> ResolveStepsAsync(PipelineContext context)\n    {\n        var annotationSteps = await CollectStepsFromAnnotationsAsync(context).ConfigureAwait(false);\n        // Configuration callbacks are run on every resolution, so give them fresh built-in steps instead","sourceCodeStart":590,"sourceCodeEnd":626,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/Pipelines/DistributedApplicationPipeline.cs#L590-L626","documentation":"When executing a single step sequentially (ExecuteStepSequentiallyAsync), the pipeline resolves the requested stepName against all registered steps using an ordinal dictionary. If the name does not match any step, it throws this InvalidOperationException and helpfully lists the available step names so the caller can see what went wrong. It is a lookup failure, not a state corruption.","triggerScenarios":"Calling the pipeline execution overload that targets a specific step name with a name that is misspelled, differs in casing, contains extra whitespace, or refers to a step that was never added (or was added under a different name).","commonSituations":"Running 'aspire publish/run --step <name>' style targeting from a script or CLI with a stale step name; renaming a step in code but not updating the caller; case-sensitivity confusion ('Deploy' vs 'deploy'); typos in test code invoking ExecuteStepSequentiallyAsync.","solutions":["Compare stepName against the available steps list printed in the exception message and correct the spelling/casing.","Enumerate registered steps (pipeline.Steps or equivalent) at runtime and pick the name programmatically instead of hardcoding it.","Ensure the step is added before execution: verify AddStep was called for the target step on this pipeline instance.","Normalize name comparison: pass exactly the step.Name value rather than a re-typed literal."],"exampleFix":"// before\nawait pipeline.ExecuteStepSequentiallyAsync(context, \"depoy\"); // typo\n// after\nvar stepName = pipeline.Steps.First(s => s.Name == \"deploy\").Name;\nawait pipeline.ExecuteStepSequentiallyAsync(context, stepName);","handlingStrategy":"validation","validationCode":"var known = pipeline.Steps.Select(s => s.Name).ToHashSet(StringComparer.Ordinal);\nif (!known.Contains(stepName))\n{\n    throw new InvalidOperationException($\"'{stepName}' is not a registered step. Known: {string.Join(\", \", known)}\");\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    await pipeline.ExecuteStepSequentiallyAsync(context, stepName);\n}\ncatch (InvalidOperationException ex) when (ex.Message.StartsWith(\"Step '\") && ex.Message.Contains(\"not found in pipeline\"))\n{\n    logger.LogError(ex, \"Unknown step '{StepName}'. Register it or fix the name.\", stepName);\n}","preventionTips":["Reference step names via constants/shared fields, never inline literals.","Match names case-sensitively (lookup is ordinal).","Trim and normalize names sourced from CLI args or config.","After renaming a step, grep for its old name across scripts and tests."],"tags":["step-not-found","pipeline","lookup-failure","csharp"],"backgroundTag":"record-not-found","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"}