microsoft/aspire · error · InvalidOperationException
Infra is not set
Error message
Infra is not set
What it means
AzureAppServiceWebsiteContext lazily caches its AzureResourceInfrastructure in _infrastructure; the Infra property throws this InvalidOperationException when accessed before BuildWebSite (or an equivalent method) has assigned it. Infra is only valid while the website is being built into an AzureResourceInfrastructure, so any use outside that phase is a programming/lifecycle error.
Solutions
- Ensure the website context's BuildWebSite(infra) runs before any code touches Infra — hook custom logic into the infrastructure-building phase, not resource-modeling phase.
- Move annotation callbacks so they execute after the context's _infrastructure is assigned (BuildWebSite sets it).
- In tests or tooling, call BuildWebSite with a real AzureResourceInfrastructure before asserting on Infra-dependent values.
Example fix
// before (annotation running too early, Infra not yet set) var infra = websiteContext.Infra; // throws // after environmentContext.BuildWebSite(infra); // assigns Infra var value = websiteContext.Infra;
Defensive patterns
Strategy: validation
Validate before calling
if (websiteContext.InfraExists /* or track via BuildWebSite having run */) { useInfra(); } else { throw new InvalidOperationException("BuildWebSite must run before accessing Infra"); } Type guard
bool InfraIsInitialized(AzureAppServiceWebsiteContext ctx) => ctx.GetType().GetField("_infrastructure", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(ctx) is not null; Try / catch
try { var infra = ctx.Infra; }
catch (InvalidOperationException ex) when (ex.Message == "Infra is not set")
{
throw new InvalidOperationException("Access websiteContext.Infra only inside the publish/build phase (after BuildWebSite).", ex);
} Prevention
- Only access Infra from code that runs during infrastructure generation (BuildWebSite, annotations invoked at publish time).
- Never read Infra during resource modeling in the AppHost.
- In tests, call BuildWebSite(infra) before asserting on Infra-dependent outputs.
When it happens
Trigger: Accessing the Infra property (directly, or indirectly through helpers like AllocateKeyVaultSecretUriReference, AllocateParameter, or BicepValue resolution that need Infra) before AzureAppServiceWebsiteContext.BuildWebSite has been called with an AzureResourceInfrastructure.
Common situations: Custom annotations or callbacks (e.g. AzureAppServiceWebsiteCustomizationAnnotation) that inspect the website context too early; calling context methods during resource modeling instead of during publish/infrastructure generation; tests instantiating the context and poking at Infra without running the build phase.
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
- The property ' ' is not supported for the endpoint ' '.
- Unsupported endpoint property
- Unsupported value type
- Unsupported value type
- A ConfigureRadiusInfrastructure callback removed or…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/6d900040506fd683.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Azure.AppService/AzureAppServiceWebsiteContext.cs:35
internal sealed class AzureAppServiceWebsiteContext(
IResource resource,
AzureAppServiceEnvironmentContext environmentContext)
{
public IResource Resource => resource;
record struct EndpointMapping(string Scheme, BicepValue<string> Host, int Port, int? TargetPort, bool IsHttpIngress, bool External);
private readonly Dictionary<string, EndpointMapping> _endpointMapping = [];
private readonly Dictionary<string, EndpointMapping> _slotEndpointMapping = [];
// Resolved environment variables and command line args
// These contain the values that need to be further transformed into
// bicep compatible values
public Dictionary<string, object> EnvironmentVariables { get; } = [];
public List<object> Args { get; } = [];
private AzureResourceInfrastructure? _infrastructure;
public AzureResourceInfrastructure Infra => _infrastructure ?? throw new InvalidOperationException("Infra is not set");
// Naming the app service is globally unique (domain names), so we use the resource group ID to create a unique name
// within the naming spec for the app service.
private BicepValue<string> HostName => BicepFunction.Take(
BicepFunction.Interpolate($"{BicepFunction.ToLower(resource.Name)}-{AzureAppServiceEnvironmentResource.GetWebSiteSuffixBicep()}"), 60);
/// <summary>
/// Gets the hostname for a deployment slot by appending the slot name to the base website name.
/// </summary>
/// <param name="deploymentSlot">The deployment slot name.</param>
/// <returns>A <see cref="BicepValue{T}"/> representing the slot hostname, truncated to the maximum allowed length.</returns>
public BicepValue<string> GetSlotHostName(BicepValue<string> deploymentSlot)
{
var websitePrefix = BicepFunction.Take(
BicepFunction.Interpolate($"{BicepFunction.ToLower(resource.Name)}-{AzureAppServiceEnvironmentResource.GetWebSiteSuffixBicep()}"), AzureAppServiceWebSiteResource.MaxWebSiteNamePrefixLengthWithSlot);
return BicepFunction.Take(
BicepFunction.Interpolate($"{websitePrefix}-{BicepFunction.ToLower(deploymentSlot)}"), AzureAppServiceWebSiteResource.MaxHostPrefixLengthWithSlot);View on GitHub (pinned to 25830f84bd)