microsoft/aspire · error · InvalidOperationException
Azure sandbox group ' ' returned an invalid resource ID ' '.
Error message
Azure sandbox group '{sandboxGroup.Name}' returned an invalid resource ID '{resourceId}'. What it means
Thrown when the 'id' output of an Azure sandbox group parses to an Azure.Core.ResourceIdentifier whose SubscriptionId, ResourceGroupName, or Name component is empty. The library needs those three components to build an AzureDevComputeResourceScope and rejects any malformed resource ID.
Solutions
- Verify the sandbox group's 'id' output is a full ARM resource ID: /subscriptions/{sub}/resourceGroups/{rg}/providers/{ns}/{type}/{name}.
- Regenerate the deployment state by re-running provisioning so a well-formed ID is emitted.
- If using a custom Bicep template, output the resource's `.id` property directly rather than constructing it manually.
- Check that resourceId.Name (not the collection-level ID) is being emitted by the template.
Example fix
// before
output id string = '/subscriptions/${sub}/sandboxGroups/${name}'
// after
output id string = sandboxGroup.id Defensive patterns
Strategy: validation
Validate before calling
static bool IsValidArmId(string id) =>
id.StartsWith("/subscriptions/") && id.Split('/').Length >= 9; Type guard
static bool TryParseScope(string id, out (string Sub, string Rg, string Name) scope)
{
var rid = new Azure.Core.ResourceIdentifier(id);
scope = (rid.SubscriptionId ?? "", rid.ResourceGroupName ?? "", rid.Name ?? "");
return scope.Sub != "" && scope.Rg != "" && scope.Name != "";
} Prevention
- Always emit full ARM resource IDs from Bicep outputs (use resource.id).
- Do not construct resource IDs by string concatenation.
- Validate deployment-state IDs after every provisioning run in CI.
When it happens
Trigger: CreateDataPlaneScope building `new ResourceIdentifier(GetRequiredOutput(sandboxGroup, "id"))` where the id string is not a fully-qualified ARM resource ID (missing subscription, resource group, or name segments).
Common situations: A hand-modified or mocked deployment state containing a partial ID like '/subscriptions/.../sandboxGroups' without a name; a custom Bicep template outputting an incomplete ID; typo'd ARM ID format.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- App Service configuration validation failed. See errors…
- App Service plan id ' ' does not contain a subscription id.
- AppHost:DeploymentStatePathSha256 is required to isolate…
- At least one connector operation must be explicitly…
- Azure sandbox deployment state for resource
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/cfbf639f6f203666.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Azure.Sandboxes/AzureSandboxContainerDeployment.cs:2332
{
if (!resource.Outputs.TryGetValue(name, out var value) || value is null || string.IsNullOrWhiteSpace(value.ToString()))
{
throw new InvalidOperationException($"Azure resource '{resource.Name}' is missing required output '{name}'. Ensure Azure infrastructure provisioning completed successfully.");
}
return value.ToString()!;
}
internal static AzureDevComputeResourceScope CreateDataPlaneScope(AzureSandboxGroupResource sandboxGroup)
{
ArgumentNullException.ThrowIfNull(sandboxGroup);
var resourceId = new global::Azure.Core.ResourceIdentifier(GetRequiredOutput(sandboxGroup, "id"));
if (string.IsNullOrWhiteSpace(resourceId.SubscriptionId) ||
string.IsNullOrWhiteSpace(resourceId.ResourceGroupName) ||
string.IsNullOrWhiteSpace(resourceId.Name))
{
throw new InvalidOperationException(
$"Azure sandbox group '{sandboxGroup.Name}' returned an invalid resource ID '{resourceId}'.");
}
return new AzureDevComputeResourceScope(
resourceId.SubscriptionId,
resourceId.ResourceGroupName,
resourceId.Name,
GetRequiredOutput(sandboxGroup, "location"));
}
private static string CreateSandboxResourceName(string resourceName, string deployId)
{
var normalized = new string(resourceName.ToLowerInvariant().Select(static c => char.IsLetterOrDigit(c) ? c : '-').ToArray()).Trim('-');
if (string.IsNullOrWhiteSpace(normalized))
{
normalized = "app";
}
View on GitHub (pinned to 25830f84bd)