{"record":{"id":"a8040d3034b72000","repo":"microsoft/aspire","slug":"azureenvironmentresource-must-be-present-in-the-application","errorCode":null,"errorMessage":"AzureEnvironmentResource must be present in the application model.","messagePattern":"AzureEnvironmentResource must be present in the application model\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Azure.ContainerRegistry/AzureContainerRegistryHelpers.cs","lineNumber":27,"sourceCode":"using Aspire.Hosting.ApplicationModel;\nusing Aspire.Hosting.Pipelines;\nusing Microsoft.Extensions.DependencyInjection;\n\nnamespace Aspire.Hosting.Azure;\n\n/// <summary>\n/// Helper methods for Azure Container Registry operations.\n/// </summary>\ninternal static class AzureContainerRegistryHelpers\n{\n    public static async Task LoginToRegistryAsync(IContainerRegistry registry, PipelineStepContext context)\n    {\n        var acrLoginService = context.Services.GetRequiredService<IAcrLoginService>();\n        var tokenCredentialProvider = context.Services.GetRequiredService<ITokenCredentialProvider>();\n\n        // Find the AzureEnvironmentResource from the application model\n        var azureEnvironment = context.Model.Resources.OfType<AzureEnvironmentResource>().FirstOrDefault() ??\n            throw new InvalidOperationException(\"AzureEnvironmentResource must be present in the application model.\");\n        var registryName = await registry.Name.GetValueAsync(context.CancellationToken).ConfigureAwait(false) ??\n            throw new InvalidOperationException(\"Failed to retrieve container registry information.\");\n\n        var registryEndpoint = await registry.Endpoint.GetValueAsync(context.CancellationToken).ConfigureAwait(false) ??\n            throw new InvalidOperationException(\"Failed to retrieve container registry endpoint.\");\n\n        var loginTask = await context.ReportingStep.CreateTaskAsync(\n            new MarkdownString($\"Logging in to **{registryName}**\"),\n            context.CancellationToken).ConfigureAwait(false);\n        await using (loginTask.ConfigureAwait(false))\n        {\n            try\n            {\n                // Get tenant ID from the provisioning context (always available from subscription)\n                var provisioningContext = await azureEnvironment.ProvisioningContextTask.Task.ConfigureAwait(false);\n                var tenantId = provisioningContext.Tenant.TenantId?.ToString()\n                    ?? throw new InvalidOperationException(\"Tenant ID is required for ACR authentication but was not available in provisioning context.\");\n","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Azure.ContainerRegistry/AzureContainerRegistryHelpers.cs#L9-L45","documentation":"LoginToRegistryAsync needs the application model to contain an AzureEnvironmentResource, which supplies the provisioning context (tenant, subscription) used for ACR token authentication. If no such resource exists in the model, the lookup returns null and the library throws InvalidOperationException.","triggerScenarios":"Running a publish/deploy workflow that references an AzureContainerRegistryResource (or performs registry login) without ever calling AddAzureEnvironment on the distributed application builder, so the model contains no AzureEnvironmentResource.","commonSituations":"Copy-pasting an AppHost that adds a container registry without the Azure environment setup; adding an ACR to an existing app that was created before AzureEnvironmentResource was introduced; removing the Azure environment resource during refactoring while keeping registry infrastructure.","solutions":["Call builder.AddAzureEnvironment(...) in your AppHost before adding the container registry resource.","Verify with context.Model.Resources that exactly one AzureEnvironmentResource exists when debugging the app model.","Upgrade or align all Azure hosting packages so the environment resource is registered by the standard Azure provisioning path.","If login is invoked from custom tooling, ensure the same IDistributedApplicationBuilder instance that contains the registry also contains the environment resource."],"exampleFix":"// before\nvar registry = builder.AddAzureContainerRegistry(\"acr\");\n// after\nbuilder.AddAzureEnvironment(\"azure-env\");\nvar registry = builder.AddAzureContainerRegistry(\"acr\");","handlingStrategy":"validation","validationCode":"var azureEnv = appBuilder.Resources.OfType<AzureEnvironmentResource>().FirstOrDefault();\nif (azureEnv is null)\n{\n    throw new InvalidOperationException(\"Call builder.AddAzureEnvironment before registry login/publish.\");\n}","typeGuard":"var azureEnv = appBuilder.Resources.OfType<AzureEnvironmentResource>().FirstOrDefault();\nbool hasAzureEnvironment = azureEnv is not null;","tryCatchPattern":"try\n{\n    await LoginToRegistryAsync(registry, context);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"AzureEnvironmentResource\"))\n{\n    logger.LogError(\"App model is missing AzureEnvironmentResource; add builder.AddAzureEnvironment().\");\n    throw;\n}","preventionTips":["Always call AddAzureEnvironment in AppHosts that add Azure infrastructure resources.","Review AppHost templates after upgrading packages that introduced AzureEnvironmentResource.","Add a startup assertion in custom tooling that the environment resource exists before login operations."],"tags":["azure","application-model","container-registry","missing-resource"],"backgroundTag":"missing-dependency","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"}