microsoft/aspire · info · OperationCanceledException

Destroy operation canceled by user.

Error message

Destroy operation canceled by user.

What it means

After the interactive confirmation prompt, if the user cancels or declines (result.Canceled or result.Data == false), the controller logs the cancellation and throws OperationCanceledException to abort the destroy pipeline before deleting the resource group.

Solutions

  1. Answer Yes/confirm at the prompt if you actually want to destroy the resources
  2. Re-run the command and confirm to proceed with deletion
  3. Treat the OperationCanceledException as a benign no-op in scripts and exit gracefully

Example fix

// before
// user cancels prompt -> OperationCanceledException
// after
if (result.Canceled)
{
    Console.WriteLine("Destroy canceled; no changes made.");
    return;
}
Defensive patterns

Strategy: try-catch

Try / catch

try { await DestroyAzureResourcesAsync(...); } catch (OperationCanceledException) { /* user canceled; treat as no-op */ }

Prevention

When it happens

Trigger: Answering No / cancelling at the destroy confirmation prompt; sending Ctrl+C during the confirmation interaction.

Common situations: Users running aspire destroy interactively and reconsidering; accidentally triggering destroy and aborting at the prompt; automation piping a cancel answer.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/78ada6e7b654b547. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Azure/AzureEnvironmentResource.cs:353

                : $"Delete resource group '{resourceGroupName}'? This action cannot be undone.";

            var result = await interactionService.PromptNotificationAsync(
                "Destroy Azure resources",
                confirmMessage,
                new NotificationInteractionOptions
                {
                    Intent = MessageIntent.Confirmation,
                    ShowSecondaryButton = true,
                    ShowDismiss = false,
                    PrimaryButtonText = "Destroy",
                    SecondaryButtonText = "Cancel"
                },
                context.CancellationToken).ConfigureAwait(false);

            if (result.Canceled || !result.Data)
            {
                context.Logger.LogInformation("User canceled the destroy operation.");
                throw new OperationCanceledException("Destroy operation canceled by user.");
            }
        }

        // Delete the resource group
        var deleteTask = await context.ReportingStep.CreateTaskAsync(
            new MarkdownString($"Deleting resource group **{resourceGroupName}** ({resources.Count} resource(s))"),
            context.CancellationToken).ConfigureAwait(false);
        await using var __ = deleteTask.ConfigureAwait(false);

        try
        {
            await resourceGroup.DeleteAsync(WaitUntil.Started, context.CancellationToken).ConfigureAwait(false);

            var portalUrl = AzurePortalUrls.GetResourceGroupUrl(subscriptionId, resourceGroupName, subscription.TenantId);
            context.Summary.Add("🗑️ Resource Group", new MarkdownString($"[{resourceGroupName}]({portalUrl})"));
            context.Summary.Add("🔑 Subscription", subscriptionId);
            context.Summary.Add("⏳ Status", new MarkdownString($"Deletion in progress. Monitor [here]({portalUrl})"));

View on GitHub (pinned to 25830f84bd)