microsoft/aspire · error · InvalidOperationException

GatewayAppsAnnotation not found on resource.

Error message

GatewayAppsAnnotation not found on resource.

What it means

GetRegisteredApps reads the GatewayAppsAnnotation from the gateway resource to enumerate the registered Blazor apps. If the annotation is absent — meaning WithBlazorApp (or equivalent registration) was never applied to this resource — the helper throws an InvalidOperationException.

Solutions

  1. Call gateway.WithBlazorApp(...) (which adds GatewayAppsAnnotation) before code that reads registered apps.
  2. Register at least one Blazor app with the gateway via the documented extension APIs.
  3. Guard with resource.TryGetLastAnnotation<GatewayAppsAnnotation> before consuming apps.
  4. Ensure you're inspecting the gateway resource itself, not the client app resource.

Example fix

// before
var apps = GetRegisteredApps(gateway.Resource);
// after
if (!gateway.Resource.TryGetLastAnnotation<GatewayAppsAnnotation>(out var appsAnn))
{
    throw new InvalidOperationException("Call WithBlazorApp on the gateway before starting it.");
}
var apps = appsAnn.Apps;
Defensive patterns

Strategy: type-guard

Validate before calling

if (!gateway.Resource.TryGetLastAnnotation<GatewayAppsAnnotation>(out var apps))
{
    throw new InvalidOperationException("No Blazor apps registered; call WithBlazorApp first.");
}

Type guard

bool TryGetGatewayApps(IResource r, out IReadOnlyList<BlazorApp> apps)
{
    if (r.TryGetLastAnnotation<GatewayAppsAnnotation>(out var a)) { apps = a.Apps; return true; }
    apps = default; return false;
}

Try / catch

try { var apps = GetRegisteredApps(gateway.Resource); } catch (InvalidOperationException ex) when (ex.Message.Contains("GatewayAppsAnnotation")) { logger.LogError(ex, "Call WithBlazorApp before consuming gateway apps"); throw; }

Prevention

When it happens

Trigger: Environment-callback or endpoint wiring code calls GetRegisteredApps on a gateway resource that never received GatewayAppsAnnotation, e.g. invoking WithBlazorApp-dependent configuration on a gateway built without registering any Blazor app.

Common situations: Calling low-level extension methods out of order; applying WithEnvironment-based wiring manually before any WithBlazorApp call; a refactor renamed/removed the registration call.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/a774148ba505737d. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Blazor/BlazorGatewayExtensions.cs:706

    {
        if (resource.TryGetLastAnnotation<GatewayAppsAnnotation>(out var existing))
        {
            return existing;
        }

        var newAnnotation = new GatewayAppsAnnotation();
        resource.Annotations.Add(newAnnotation);
        return newAnnotation;
    }

    private static List<GatewayAppRegistration> GetRegisteredApps(IResource resource)
    {
        if (resource.TryGetLastAnnotation<GatewayAppsAnnotation>(out var apps))
        {
            return apps.Apps;
        }

        throw new InvalidOperationException("GatewayAppsAnnotation not found on resource.");
    }

    private static List<EndpointAnnotation> GetAllocatedEndpoints(IResource resource)
    {
        var endpoints = new List<EndpointAnnotation>();
        foreach (var annotation in resource.Annotations)
        {
            if (annotation is EndpointAnnotation ep && ep.AllocatedEndpoint is not null)
            {
                endpoints.Add(ep);
            }
        }
        return endpoints;
    }

    private static ImmutableArray<UrlSnapshot> BuildClientUrls(
        List<EndpointAnnotation> endpoints, string pathPrefix)
    {

View on GitHub (pinned to 25830f84bd)