microsoft/aspire · error · InvalidOperationException
The dashboard URL is not available in publish mode.
Error message
The dashboard URL is not available in publish mode.
What it means
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.
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.
Example fix
// before
var url = await app.GetDashboardUrlAsync();
// after
var ctx = app.Services.GetRequiredService<DistributedApplicationExecutionContext>();
if (!ctx.IsPublishMode)
{
var url = await app.GetDashboardUrlAsync();
} Defensive patterns
Strategy: validation
Validate before calling
var ctx = app.Services.GetRequiredService<DistributedApplicationExecutionContext>();
if (ctx.IsPublishMode)
{
// skip dashboard URL retrieval; return null or take alternate path
} Type guard
static bool CanGetDashboardUrl(DistributedApplication app) =>
!app.Services.GetRequiredService<DistributedApplicationExecutionContext>().IsPublishMode; Try / catch
try
{
var url = await app.GetDashboardUrlAsync(ct);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("publish mode"))
{
url = null; // publish mode: dashboard has no runtime URL
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Shared helper code that runs both run and publish paths calling the extension unconditionally; custom deploy pipelines invoking testing extensions during manifest generation.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Dashboard testing is not supported in publish mode.
- The dashboard is not enabled for this application.
- The dashboard URL is not available.
- AppHost:ResourceService:ApiKey is not specified in…
- Application did not register an implementation of
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/e31c5688baa72139.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Testing/DistributedApplicationHostingTestingExtensions.cs:74
///
/// var builder = await DistributedApplicationTestingBuilder.CreateAsync<Projects.MyAppHost_AppHost>(options, []);
/// await using var app = await builder.BuildAsync();
/// await app.StartAsync();
///
/// var dashboardUrl = await app.GetDashboardUrlAsync();
/// </code>
/// </example>
[AspireExportIgnore(Reason = "Use the exported getDashboardUrl overload without a cancellation token.")]
public static async Task<Uri> GetDashboardUrlAsync(
this DistributedApplication app,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(app);
var executionContext = app.Services.GetRequiredService<DistributedApplicationExecutionContext>();
if (executionContext.IsPublishMode)
{
throw new InvalidOperationException(Properties.Resources.DashboardUrlPublishModeExceptionMessage);
}
var applicationOptions = app.Services.GetRequiredService<DistributedApplicationOptions>();
if (applicationOptions.DisableDashboard)
{
throw new InvalidOperationException(Properties.Resources.DashboardDisabledExceptionMessage);
}
ThrowIfNotStarted(app, Properties.Resources.DashboardUrlApplicationNotStartedExceptionMessage);
cancellationToken.ThrowIfCancellationRequested();
await app.ResourceNotifications.WaitForResourceHealthyAsync(
DashboardResourceName,
WaitBehavior.StopOnResourceUnavailable,
cancellationToken).ConfigureAwait(false);
var applicationModel = app.Services.GetRequiredService<DistributedApplicationModel>();
if (!applicationModel.Resources.TryGetByName(DashboardResourceName, out var resource) ||View on GitHub (pinned to 25830f84bd)