{"record":{"id":"767abe3d7c1426f6","repo":"microsoft/aspire","slug":"run-completed-without-returning-a-backchannel","errorCode":null,"errorMessage":"Run completed without returning a backchannel.","messagePattern":"Run completed without returning a backchannel\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Cli/Commands/PipelineCommandBase.cs","lineNumber":322,"sourceCode":"                if (completedTask.IsFaulted && completedTask.Exception?.InnerException is DotNetSdkNotInstalledException sdkException)\n                {\n                    throw sdkException;\n                }\n\n                // When running in extension context, the extension takes over apphost management.\n                // DotNetCliRunner returns Success immediately after delegating to LaunchAppHostAsync,\n                // so pendingRun completes before the backchannel is established. In this case,\n                // continue waiting for the backchannel rather than throwing.\n                if (!completedTask.IsFaulted && await pendingRun == CliExitCodes.Success\n                    && ExtensionHelper.IsExtensionHost(InteractionService, out _, out _))\n                {\n                    return await backchannelCompletionSource.Task;\n                }\n\n                // Throw an error if the run completed without returning a backchannel.\n                // Include possible error if the run task faulted.\n                var innerException = completedTask.IsFaulted ? completedTask.Exception : null;\n                throw new InvalidOperationException(\"Run completed without returning a backchannel.\", innerException);\n            }), emoji: KnownEmojis.HammerAndWrench);\n\n            // If --list-steps was specified, get pipeline steps and print them instead of executing\n            if (listSteps)\n            {\n                StopTerminalProgressBar();\n                int inspectionExitCode;\n\n                try\n                {\n                    // Check that the AppHost supports this capability before calling\n                    var capabilities = await backchannel.GetCapabilitiesAsync(cancellationToken);\n                    if (!capabilities.Contains(ListStepsCapability))\n                    {\n                        throw new AppHostIncompatibleException(\n                            ListStepsIncompatibleMessage,\n                            ListStepsCapability);\n                    }","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Cli/Commands/PipelineCommandBase.cs#L304-L340","documentation":"PipelineCommandBase awaits a backchannelCompletionSource that the running AppHost task must complete with an auxiliary backchannel. If the run task completes (successfully or faulted) without ever setting a backchannel, ExecuteAsync throws InvalidOperationException, including the run task's exception as InnerException when it faulted.","triggerScenarios":"The AppHost run task finished without publishing a backchannel — the AppHost exited before establishing the auxiliary backchannel, the hosted run failed (faulted task), or an older AppHost never wires the backchannel completion.","commonSituations":"'aspire pipeline' against an AppHost that crashes on startup or exits immediately; AppHost version too old to return a backchannel; run cancelled before the backchannel handshake completed.","solutions":["Check the InnerException / AppHost run output for the underlying startup failure and fix it","Update the AppHost's Aspire.Hosting packages so it establishes the backchannel (see the related --list-steps incompatibility)","Rerun 'aspire pipeline' after the AppHost starts successfully; add a hangdump/timeout to diagnose stalls"],"exampleFix":"// before\naspire pipeline ./MyApp.AppHost/MyApp.AppHost.csproj\n// after\ndotnet run --project MyApp.AppHost   # first verify the AppHost starts and stays running\naspire pipeline ./MyApp.AppHost/MyApp.AppHost.csproj","handlingStrategy":"try-catch","validationCode":"// verify the AppHost starts and stays up before running pipelines\ndotnet run --project MyApp.AppHost & sleep 10\nkill %1  # only proceed if startup output showed no errors","typeGuard":null,"tryCatchPattern":"try\n{\n    await pipeline.ExecuteAsync(...);\n}\ncatch (InvalidOperationException ex) when (ex.Message == \"Run completed without returning a backchannel.\")\n{\n    Console.Error.WriteLine($\"AppHost run failed before backchannel setup: {ex.InnerException?.Message}\");\n    throw ex.InnerException ?? ex;\n}","preventionTips":["Confirm the AppHost runs cleanly (dotnet run) before 'aspire pipeline'","Read InnerException for the real startup failure","Update Aspire.Hosting packages so the run wires up the backchannel","Use --hangdump/--hangdump-timeout to diagnose handshake stalls"],"tags":["cli","pipeline","backchannel"],"backgroundTag":"internal-invariant-violation","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"}