microsoft/aspire · error · InvalidOperationException
The Azure sandbox group deployment scope changed while…
Error message
The Azure sandbox group deployment scope changed while sandbox deployment state still exists. Run 'aspire destroy' with the previous sandbox group configuration before deploying to the new scope.
What it means
Sandbox deployment state records the subscription, resource group, region, and sandbox group under which it was created. If any of these differ from the current deployment scope while state still exists, deploying would operate on the wrong sandbox, so an InvalidOperationException demands an 'aspire destroy' with the previous configuration first.
Solutions
- Run 'aspire destroy' with the previous sandbox group configuration to clear state, then deploy with the new scope
- Manually delete the sandbox deployment state (and the Azure resources) if destroy is not possible
- Revert the scope configuration change to match the existing state
Example fix
// before // scope changed: new subscription/resourceGroup/region/sandboxGroup, old state present -> error // after aspire destroy # with previous scope configuration aspire deploy # now with new scope
Defensive patterns
Strategy: validation
Validate before calling
// Compare current scope against state section before deploying
bool ScopeMatches(state, sub, rg, region, group) =>
string.Equals(state.SubscriptionId, sub, OrdinalIgnoreCase) &&
string.Equals(state.ResourceGroupName, rg, OrdinalIgnoreCase) &&
string.Equals(state.Region, region, OrdinalIgnoreCase) &&
string.Equals(state.SandboxGroupName, group, OrdinalIgnoreCase); Try / catch
try { DeploySandbox(...); } catch (InvalidOperationException ex) when (ex.Message.Contains("deployment scope changed")) { /* run aspire destroy with previous scope, then redeploy */ } Prevention
- Run 'aspire destroy' before changing subscription/resource group/region/sandbox group
- Keep scope values stable across deployments sharing state
When it happens
Trigger: Changing subscription ID, resource group name, region, or sandbox group name (case-insensitive comparison) in the sandbox configuration without destroying the existing sandbox deployment state.
Common situations: Moving a project to a different Azure subscription or region; renaming the resource group or sandbox group; switching between environments that share a state file.
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
- AppHost:DeploymentStatePathSha256 is required to isolate…
- Endpoint ' ' on resource ' ' is not exposed by the Azure…
- Azure sandbox deployment state for resource
- Azure sandbox endpoint
- Azure sandbox group ' ' returned an invalid resource ID ' '.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/c03c3bd30d78cc36.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Azure.Sandboxes/AzureSandboxContainerDeployment.cs:2130
var subscriptionId = stateSection.Data["SubscriptionId"]?.GetValue<string>();
var resourceGroup = stateSection.Data["ResourceGroup"]?.GetValue<string>();
var location = stateSection.Data["Location"]?.GetValue<string>();
var sandboxGroup = stateSection.Data["SandboxGroup"]?.GetValue<string>();
if (string.IsNullOrWhiteSpace(subscriptionId) ||
string.IsNullOrWhiteSpace(resourceGroup) ||
string.IsNullOrWhiteSpace(location) ||
string.IsNullOrWhiteSpace(sandboxGroup))
{
return;
}
if (!string.Equals(subscriptionId, scope.SubscriptionId, StringComparison.OrdinalIgnoreCase) ||
!string.Equals(resourceGroup, scope.ResourceGroupName, StringComparison.OrdinalIgnoreCase) ||
!string.Equals(location, scope.Region, StringComparison.OrdinalIgnoreCase) ||
!string.Equals(sandboxGroup, scope.SandboxGroupName, StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException(
"The Azure sandbox group deployment scope changed while sandbox deployment state still exists. " +
"Run 'aspire destroy' with the previous sandbox group configuration before deploying to the new scope.");
}
}
internal static bool HasRemoteDeploymentState(DeploymentStateSection stateSection) =>
!string.IsNullOrWhiteSpace(stateSection.Data["OwnerId"]?.GetValue<string>()) ||
!string.IsNullOrWhiteSpace(stateSection.Data["SandboxId"]?.GetValue<string>()) ||
!string.IsNullOrWhiteSpace(stateSection.Data["DiskImageId"]?.GetValue<string>());
internal static string CreateSandboxUrlSummary(string currentUrl, string? retainedUrl)
{
if (string.IsNullOrWhiteSpace(retainedUrl) ||
string.Equals(currentUrl, retainedUrl, StringComparison.Ordinal))
{
return $"[{currentUrl}]({currentUrl})";
}
View on GitHub (pinned to 25830f84bd)