microsoft/aspire · error · InvalidOperationException

Step with ID ' ' does not exist.

Error message

Step with ID '{step.Id}' does not exist.

What it means

PipelineActivityReporter.CreateTaskAsync creates a child ReportingTask under an existing ReportingStep. It looks the step up by ID in the reporter's internal step dictionary; if the ID is absent the step was never registered with this reporter (or was already removed), so an InvalidOperationException is thrown rather than silently attaching a task to nothing.

Solutions

  1. Create the task via the same reporter that owns the step (e.g. context.ReportingStep.CreateTaskAsync inside the pipeline step).
  2. Verify the step was registered first (CreateStepAsync on the same reporter) before creating tasks under it.
  3. In tests, use one reporter instance for both the step creation and task creation.
  4. Check lifecycle ordering: do not create tasks after the activity has completed/cleared steps.

Example fix

// before
await wrongReporter.CreateTaskAsync(step, text, false);
// after
await step.Reporter.CreateTaskAsync(step, text, false);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!reporterOwnsStep) throw new InvalidOperationException("Step not registered with this reporter.");

Type guard

null

Try / catch

try { await reporter.CreateTaskAsync(step, text, false); } catch (InvalidOperationException ex) when (ex.Message.Contains("does not exist")) { logger.LogWarning(ex, "Skipping task creation: step not registered."); }

Prevention

When it happens

Trigger: Calling reporter.CreateTaskAsync(step, ...) with a ReportingStep instance whose Id was never passed to this reporter (e.g. a step created by a different PipelineActivityReporter instance, or after the step's parent pipeline context was torn down).

Common situations: Sharing a ReportingStep across two reporters in tests, calling CreateTaskAsync after the deployment/publish activity completed and steps were cleared, or constructing a step manually instead of receiving it from PipelineStepContext.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting/Pipelines/PipelineActivityReporter.cs:86

        var step = new ReportingStep(this, Guid.NewGuid().ToString(), title, resolvedParentStepId, hierarchyLevel);
        _steps.TryAdd(step.Id, step);
        _stepIdsByTitle[title] = step.Id;

        var state = new PublishingActivity
        {
            Type = PublishingActivityTypes.Step,
            Data = CreateStepActivityData(step, step.Title, CompletionState.InProgress, enableMarkdown: false)
        };

        await ActivityItemUpdated.Writer.WriteAsync(state, cancellationToken).ConfigureAwait(false);
        return step;
    }

    public async Task<ReportingTask> CreateTaskAsync(ReportingStep step, string statusText, bool enableMarkdown, CancellationToken cancellationToken)
    {
        if (!_steps.TryGetValue(step.Id, out var parentStep))
        {
            throw new InvalidOperationException($"Step with ID '{step.Id}' does not exist.");
        }

        lock (parentStep)
        {
            if (parentStep.CompletionState != CompletionState.InProgress)
            {
                throw new InvalidOperationException($"Cannot create task for step '{step.Id}' because the step is already complete.");
            }
        }

        var task = new ReportingTask(Guid.NewGuid().ToString(), step.Id, statusText, parentStep);

        // Add task to parent step
        parentStep.AddTask(task);

        var state = new PublishingActivity
        {
            Type = PublishingActivityTypes.Task,

View on GitHub (pinned to 25830f84bd)