{"record":{"id":"c03c3bd30d78cc36","repo":"microsoft/aspire","slug":"the-azure-sandbox-group-deployment-scope-changed-while","errorCode":null,"errorMessage":"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.","messagePattern":"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\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Azure.Sandboxes/AzureSandboxContainerDeployment.cs","lineNumber":2130,"sourceCode":"\n        var subscriptionId = stateSection.Data[\"SubscriptionId\"]?.GetValue<string>();\n        var resourceGroup = stateSection.Data[\"ResourceGroup\"]?.GetValue<string>();\n        var location = stateSection.Data[\"Location\"]?.GetValue<string>();\n        var sandboxGroup = stateSection.Data[\"SandboxGroup\"]?.GetValue<string>();\n        if (string.IsNullOrWhiteSpace(subscriptionId) ||\n            string.IsNullOrWhiteSpace(resourceGroup) ||\n            string.IsNullOrWhiteSpace(location) ||\n            string.IsNullOrWhiteSpace(sandboxGroup))\n        {\n            return;\n        }\n\n        if (!string.Equals(subscriptionId, scope.SubscriptionId, StringComparison.OrdinalIgnoreCase) ||\n            !string.Equals(resourceGroup, scope.ResourceGroupName, StringComparison.OrdinalIgnoreCase) ||\n            !string.Equals(location, scope.Region, StringComparison.OrdinalIgnoreCase) ||\n            !string.Equals(sandboxGroup, scope.SandboxGroupName, StringComparison.OrdinalIgnoreCase))\n        {\n            throw new InvalidOperationException(\n                \"The Azure sandbox group deployment scope changed while sandbox deployment state still exists. \" +\n                \"Run 'aspire destroy' with the previous sandbox group configuration before deploying to the new scope.\");\n        }\n    }\n\n    internal static bool HasRemoteDeploymentState(DeploymentStateSection stateSection) =>\n        !string.IsNullOrWhiteSpace(stateSection.Data[\"OwnerId\"]?.GetValue<string>()) ||\n        !string.IsNullOrWhiteSpace(stateSection.Data[\"SandboxId\"]?.GetValue<string>()) ||\n        !string.IsNullOrWhiteSpace(stateSection.Data[\"DiskImageId\"]?.GetValue<string>());\n\n    internal static string CreateSandboxUrlSummary(string currentUrl, string? retainedUrl)\n    {\n        if (string.IsNullOrWhiteSpace(retainedUrl) ||\n            string.Equals(currentUrl, retainedUrl, StringComparison.Ordinal))\n        {\n            return $\"[{currentUrl}]({currentUrl})\";\n        }\n","sourceCodeStart":2112,"sourceCodeEnd":2148,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Azure.Sandboxes/AzureSandboxContainerDeployment.cs#L2112-L2148","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n// scope changed: new subscription/resourceGroup/region/sandboxGroup, old state present -> error\n// after\naspire destroy   # with previous scope configuration\naspire deploy    # now with new scope","handlingStrategy":"validation","validationCode":"// Compare current scope against state section before deploying\nbool ScopeMatches(state, sub, rg, region, group) =>\n    string.Equals(state.SubscriptionId, sub, OrdinalIgnoreCase) &&\n    string.Equals(state.ResourceGroupName, rg, OrdinalIgnoreCase) &&\n    string.Equals(state.Region, region, OrdinalIgnoreCase) &&\n    string.Equals(state.SandboxGroupName, group, OrdinalIgnoreCase);","typeGuard":null,"tryCatchPattern":"try { DeploySandbox(...); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"deployment scope changed\")) { /* run aspire destroy with previous scope, then redeploy */ }","preventionTips":["Run 'aspire destroy' before changing subscription/resource group/region/sandbox group","Keep scope values stable across deployments sharing state"],"tags":["azure","sandbox","deployment-scope","state"],"backgroundTag":"invalid-state-transition","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"}