{"record":{"id":"e31c5688baa72139","repo":"microsoft/aspire","slug":"the-dashboard-url-is-not-available-in-publish-mode","errorCode":null,"errorMessage":"The dashboard URL is not available in publish mode.","messagePattern":"The dashboard URL is not available in publish mode\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Testing/DistributedApplicationHostingTestingExtensions.cs","lineNumber":74,"sourceCode":"    ///\n    /// var builder = await DistributedApplicationTestingBuilder.CreateAsync&lt;Projects.MyAppHost_AppHost&gt;(options, []);\n    /// await using var app = await builder.BuildAsync();\n    /// await app.StartAsync();\n    ///\n    /// var dashboardUrl = await app.GetDashboardUrlAsync();\n    /// </code>\n    /// </example>\n    [AspireExportIgnore(Reason = \"Use the exported getDashboardUrl overload without a cancellation token.\")]\n    public static async Task<Uri> GetDashboardUrlAsync(\n        this DistributedApplication app,\n        CancellationToken cancellationToken = default)\n    {\n        ArgumentNullException.ThrowIfNull(app);\n\n        var executionContext = app.Services.GetRequiredService<DistributedApplicationExecutionContext>();\n        if (executionContext.IsPublishMode)\n        {\n            throw new InvalidOperationException(Properties.Resources.DashboardUrlPublishModeExceptionMessage);\n        }\n\n        var applicationOptions = app.Services.GetRequiredService<DistributedApplicationOptions>();\n        if (applicationOptions.DisableDashboard)\n        {\n            throw new InvalidOperationException(Properties.Resources.DashboardDisabledExceptionMessage);\n        }\n\n        ThrowIfNotStarted(app, Properties.Resources.DashboardUrlApplicationNotStartedExceptionMessage);\n        cancellationToken.ThrowIfCancellationRequested();\n\n        await app.ResourceNotifications.WaitForResourceHealthyAsync(\n            DashboardResourceName,\n            WaitBehavior.StopOnResourceUnavailable,\n            cancellationToken).ConfigureAwait(false);\n\n        var applicationModel = app.Services.GetRequiredService<DistributedApplicationModel>();\n        if (!applicationModel.Resources.TryGetByName(DashboardResourceName, out var resource) ||","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Testing/DistributedApplicationHostingTestingExtensions.cs#L56-L92","documentation":"GetDashboardUrlAsync resolves the dashboard's HTTP endpoint, which only exists when the app runs (run mode). In publish mode the app is generating deployment artifacts, no dashboard resource/endpoint is instantiated, so the extension refuses to proceed. It is a guard against a meaningless call rather than a runtime failure.","triggerScenarios":"Calling app.GetDashboardUrlAsync() on a DistributedApplication whose DistributedApplicationExecutionContext is in publish mode — i.e. inside PublishAsDockerFile/GenerateResource pipeline or after running with --publisher / publish operations.","commonSituations":"Shared helper code that runs both run and publish paths calling the extension unconditionally; custom deploy pipelines invoking testing extensions during manifest generation.","solutions":["Call GetDashboardUrlAsync only in run mode (DcpScheduler/run path), not during publish.","Check executionContext.IsPublishMode before calling and skip dashboard URL retrieval in publish mode.","Restructure the code so publish-time logic does not depend on dashboard endpoints."],"exampleFix":"// before\nvar url = await app.GetDashboardUrlAsync();\n// after\nvar ctx = app.Services.GetRequiredService<DistributedApplicationExecutionContext>();\nif (!ctx.IsPublishMode)\n{\n    var url = await app.GetDashboardUrlAsync();\n}","handlingStrategy":"validation","validationCode":"var ctx = app.Services.GetRequiredService<DistributedApplicationExecutionContext>();\nif (ctx.IsPublishMode)\n{\n    // skip dashboard URL retrieval; return null or take alternate path\n}","typeGuard":"static bool CanGetDashboardUrl(DistributedApplication app) =>\n    !app.Services.GetRequiredService<DistributedApplicationExecutionContext>().IsPublishMode;","tryCatchPattern":"try\n{\n    var url = await app.GetDashboardUrlAsync(ct);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"publish mode\"))\n{\n    url = null; // publish mode: dashboard has no runtime URL\n}","preventionTips":["Branch on DistributedApplicationExecutionContext.IsPublishMode in shared helpers.","Keep testing/dashboard URL logic out of publish-time code paths.","Document in helpers that GetDashboardUrlAsync is run-mode only."],"tags":["testing","dashboard","publish-mode"],"backgroundTag":"unsupported-operation","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"}