{"record":{"id":"90acacb8d1e2e7b9","repo":"microsoft/aspire","slug":"cannot-complete-step-reporter-is-not-set","errorCode":null,"errorMessage":"Cannot complete step: Reporter is not set.","messagePattern":"Cannot complete step: Reporter is not set\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/Pipelines/ReportingStep.cs","lineNumber":171,"sourceCode":"    /// <inheritdoc />\n    public void Log(LogLevel logLevel, MarkdownString message)\n    {\n        ArgumentNullException.ThrowIfNull(message);\n\n        if (Reporter is null)\n        {\n            return;\n        }\n\n        Reporter.Log(this, logLevel, message.Value, enableMarkdown: true);\n    }\n\n    /// <inheritdoc />\n    public async Task CompleteAsync(string completionText, CompletionState completionState = CompletionState.Completed, CancellationToken cancellationToken = default)\n    {\n        if (Reporter is null)\n        {\n            throw new InvalidOperationException(\"Cannot complete step: Reporter is not set.\");\n        }\n\n        await Reporter.CompleteStepAsync(this, completionText, completionState, enableMarkdown: false, cancellationToken: cancellationToken).ConfigureAwait(false);\n    }\n\n    /// <inheritdoc />\n    public async Task CompleteAsync(MarkdownString completionText, CompletionState completionState = CompletionState.Completed, CancellationToken cancellationToken = default)\n    {\n        ArgumentNullException.ThrowIfNull(completionText);\n\n        if (Reporter is null)\n        {\n            throw new InvalidOperationException(\"Cannot complete step: Reporter is not set.\");\n        }\n\n        await Reporter.CompleteStepAsync(this, completionText.Value, completionState, enableMarkdown: true, cancellationToken: cancellationToken).ConfigureAwait(false);\n    }\n","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/Pipelines/ReportingStep.cs#L153-L189","documentation":"ReportingStep.CompleteAsync(string, CompletionState, CancellationToken) throws InvalidOperationException when Reporter is null. Completing a step requires forwarding the completion text and state to the reporter; without one the step cannot report completion. The step must be wired to a reporter for its whole lifetime.","triggerScenarios":"Calling await step.CompleteAsync(\"Done\", CompletionState.Completed) on a ReportingStep whose Reporter property was never assigned or has been cleared.","commonSituations":"Manually constructed steps in tests, custom pipeline code completing steps after pipeline context teardown, or steps created outside the standard pipeline API.","solutions":["Create and complete the step through the pipeline infrastructure so Reporter is always attached.","Assign a valid reporter before calling CompleteAsync.","Guard on Reporter is null before completing, or use a try/finally with a reporter-availability check.","In tests, register a fake reporter implementation."],"exampleFix":"// before\nawait step.CompleteAsync(\"Deployment finished\", CompletionState.Completed);\n\n// after\nif (step.Reporter is null)\n{\n    throw new InvalidOperationException(\"Attach a reporter to the step before completing it.\");\n}\nawait step.CompleteAsync(\"Deployment finished\", CompletionState.Completed);","handlingStrategy":"type-guard","validationCode":"if (step.Reporter is null)\n{\n    throw new InvalidOperationException(\"Step has no reporter; cannot complete.\");\n}","typeGuard":"bool canComplete = step.Reporter is not null;","tryCatchPattern":"try\n{\n    await step.CompleteAsync(completionText, state);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Reporter is not set\"))\n{\n    logger.LogError(ex, \"Step completion skipped: no reporter attached.\");\n}","preventionTips":["Complete steps within the same pipeline context that created them.","Avoid caching ReportingStep objects beyond pipeline lifetime.","Use pipeline-managed completion instead of manual CompleteAsync calls."],"tags":["pipelines","reporting","not-initialized"],"backgroundTag":"missing-dependency","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}