microsoft/aspire · error · InvalidOperationException
InvalidOperationException with caller-provided…
Error message
InvalidOperationException with caller-provided exceptionMessage (application must be started before this operation).
What it means
ThrowIfNotStarted throws an InvalidOperationException with the supplied message (e.g. 'application must be started...') when the host's ApplicationStarted lifetime event has not yet fired. GetDashboardUrlAsync and GetResource (and endpoint getters) require the distributed application to be running so endpoints and the model are finalized.
Solutions
- Await app.StartAsync() (or use DistributedApplicationTestingBuilder.CreateAsync, which starts the app) before querying resources/endpoints/dashboard
- Ensure StartAsync isn't faulting silently — check for earlier exceptions
- Move getter calls into the test body after startup rather than in build-time setup
Example fix
// before var app = builder.Build(); var url = await app.GetDashboardUrlAsync(); // not started // after var app = builder.Build(); await app.StartAsync(); var url = await app.GetDashboardUrlAsync();
Defensive patterns
Strategy: validation
Validate before calling
var started = app.Services.GetRequiredService<IHostApplicationLifetime>().ApplicationStarted.IsCancellationRequested; if (!started) await app.StartAsync();
Type guard
static bool IsStarted(DistributedApplication app) =>
app.Services.GetRequiredService<IHostApplicationLifetime>().ApplicationStarted.IsCancellationRequested; Try / catch
try { var resource = app.GetResource(name); }
catch (InvalidOperationException ex) when (ex.Message.Contains("started"))
{
await app.StartAsync();
} Prevention
- Always await StartAsync (or use DistributedApplicationTestingBuilder.CreateAsync which starts) before querying the app
- Check earlier StartAsync failures — a faulted start never signals ApplicationStarted
- Keep getter calls out of build-time setup code
When it happens
Trigger: Calling GetDashboardUrlAsync, GetResource, GetEndpoint, or GetConnectionStringAsync on a DistributedApplication created with builder.Build() but before StartAsync()/RunAsync() completes.
Common situations: Forgetting to await app.StartAsync() in a test; calling getters inside a factory that builds but doesn't start the app; a StartAsync faulted earlier so the started lifetime never signals.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Application did not register an implementation of
- Array params contains empty item
- Array params contains null item
- Connection string for Kusto resource
- Dashboard testing is not supported in publish mode.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/38744d61b2d07223.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Testing/DistributedApplicationHostingTestingExtensions.cs:298
// Prefer https over http to match the default service discovery behavior (https+http://),
// where https is tried first.
endpoint = GetEndpointOrDefault(resourceWithEndpoints, "https", networkIdentifier) ?? GetEndpointOrDefault(resourceWithEndpoints, "http", networkIdentifier);
}
if (endpoint is null)
{
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, Properties.Resources.EndpointForResourceNotFoundExceptionMessage, endpointName, resourceName), nameof(endpointName));
}
return endpoint.Url;
}
static void ThrowIfNotStarted(DistributedApplication app, string exceptionMessage)
{
var lifetime = app.Services.GetRequiredService<IHostApplicationLifetime>();
if (!lifetime.ApplicationStarted.IsCancellationRequested)
{
throw new InvalidOperationException(exceptionMessage);
}
}
static EndpointReference? GetEndpointOrDefault(IResourceWithEndpoints resourceWithEndpoints, string endpointName, NetworkIdentifier? networkIdentifier = default)
{
var reference = resourceWithEndpoints.GetEndpoint(endpointName, networkIdentifier ?? KnownNetworkIdentifiers.LocalhostNetwork);
return reference.IsAllocated ? reference : null;
}
}
View on GitHub (pinned to 25830f84bd)