{"record":{"id":"ad4944d16dc93483","repo":"microsoft/aspire","slug":"container-app-environment-id-containerappenvironmentid-does","errorCode":null,"errorMessage":"Container app environment id '{containerAppEnvironmentId}' does not contain a subscription id.","messagePattern":"Container app environment id '(.+?)' does not contain a subscription id\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Azure.AppContainers/ContainerAppUrls.cs","lineNumber":28,"sourceCode":"\ninternal static class ContainerAppUrls\n{\n    private const string ContainerAppResourceType = \"/providers/Microsoft.App/containerApps/\";\n\n    internal static async Task<MarkdownString> GetPortalLinkAsync(AzureContainerAppEnvironmentResource containerAppEnv, string containerAppName, CancellationToken cancellationToken)\n    {\n        var environmentIdValue = await containerAppEnv.ContainerAppEnvironmentId.GetValueAsync(cancellationToken).ConfigureAwait(false)\n            ?? throw new InvalidOperationException($\"Missing container app environment id output for '{containerAppEnv.Name}'.\");\n        var (subscriptionId, resourceGroupName) = GetSubscriptionAndResourceGroup(environmentIdValue);\n        var resourceId = $\"{AzurePortalUrls.GetResourceGroupResourceId(subscriptionId, resourceGroupName)}{ContainerAppResourceType}{containerAppName}\";\n\n        return AzurePortalUrls.GetResourceLink(resourceId);\n    }\n\n    private static (string SubscriptionId, string ResourceGroupName) GetSubscriptionAndResourceGroup(string containerAppEnvironmentId)\n    {\n        var environmentId = new ResourceIdentifier(containerAppEnvironmentId);\n        var subscriptionId = environmentId.SubscriptionId ?? throw new InvalidOperationException($\"Container app environment id '{containerAppEnvironmentId}' does not contain a subscription id.\");\n        var resourceGroupName = environmentId.ResourceGroupName ?? throw new InvalidOperationException($\"Container app environment id '{containerAppEnvironmentId}' does not contain a resource group name.\");\n\n        return (subscriptionId, resourceGroupName);\n    }\n}\n","sourceCodeStart":10,"sourceCodeEnd":34,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Azure.AppContainers/ContainerAppUrls.cs#L10-L34","documentation":"GetSubscriptionAndResourceGroup parses the environment ID with Azure ResourceIdentifier and needs a subscription component to construct a portal resource-group URL. If the parsed ID has no subscription id, this InvalidOperationException is thrown.","triggerScenarios":"ContainerAppEnvironmentId output value is not a fully-qualified ARM resource ID (e.g. a name, relative ID like /providers/..., or malformed string without /subscriptions/<id>/).","commonSituations":"Custom or stubbed environment ID values in tests/local emulation; hand-edited Bicep outputs; downstream tooling replacing the output with a non-ARM identifier.","solutions":["Ensure the environment ID is a full ARM ID: /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.App/managedEnvironments/<name>","Check the Bicep/module output for the managed environment uses its .id property","Validate the output value format before parsing with ResourceIdentifier","Fix upstream deployments that return truncated IDs"],"exampleFix":"// before\nenvOutput = \"/providers/Microsoft.App/managedEnvironments/env1\"; // no subscription\n// after\nenvOutput = \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg/providers/Microsoft.App/managedEnvironments/env1\";","handlingStrategy":"validation","validationCode":"if (Azure.ResourceManager.ResourceIdentifier.TryParse(environmentId, out var rid) && rid.SubscriptionId is not null)\n{\n    // safe to parse\n}","typeGuard":"bool HasSubscription(string? id) => id is not null && id.Contains(\"/subscriptions/\");","tryCatchPattern":"try { var link = await ContainerAppUrls.GetPortalLinkAsync(env, name, ct); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"does not contain a subscription id\")) { /* log malformed environment id */ }","preventionTips":["Always propagate full ARM resource IDs from Bicep outputs (.id, not .name)","Never hand-build resource ID strings for portal links","Validate IDs with ResourceIdentifier in custom tooling"],"tags":["azure","arm","resource-id","portal-link"],"backgroundTag":"invalid-identifier-format","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"}