microsoft/aspire · info · OperationCanceledException
Destroy operation canceled by user.
Error message
Destroy operation canceled by user.
What it means
Aspire's Helm deployment engine throws OperationCanceledException when the interactive destroy confirmation is declined or fails. Before running 'helm destroy', the engine asks the user to confirm; if the user cancels (or declines), the destroy step is deliberately aborted by throwing so the deploy pipeline stops cleanly. This is intentional cancellation, not a bug.
Solutions
- If cancellation is intentional, no fix is needed - catch OperationCanceledException around the deploy call and treat it as a graceful abort.
- Run the pipeline with confirmation pre-accepted (or use the appropriate non-interactive flag) when running in CI so the prompt does not auto-cancel.
- Inspect logs for 'User canceled the destroy operation.' to confirm the cancel came from the confirmation prompt and not an unrelated cancellation token.
Example fix
// before
await app.RunAsync(); // crashes with OperationCanceledException when destroy is declined
// after
try
{
await app.RunAsync();
}
catch (OperationCanceledException) when (destroyDeclined)
{
// user declined the destroy confirmation; treat as normal exit
} Defensive patterns
Strategy: try-catch
Validate before calling
// No pre-call validation possible: cancellation depends on the interactive prompt. // Decide up front whether your pipeline should destroy, and surface the prompt only where a user can answer.
Try / catch
try
{
await deployTask;
}
catch (OperationCanceledException ex) when (ex.Message.Contains("Destroy operation canceled"))
{
logger.LogInformation("Kubernetes destroy declined by user; aborting pipeline gracefully.");
} Prevention
- Only invoke destroy flows in interactive sessions where the confirmation prompt can be answered.
- For CI, use a non-interactive mode or pre-confirm flag instead of letting the prompt auto-cancel.
- Treat OperationCanceledException from deploy as an expected control-flow signal, not a crash.
When it happens
Trigger: Calling the Kubernetes deploy/publish pipeline's helmDestroyStep (HelmDeploymentEngine.ConfirmDestroyAsync) and answering 'no'/canceling at the destroy confirmation prompt, or the confirmation result reports Canceled=true / Data=false.
Common situations: Developers running 'aspire publish'/'deploy' destroy flows in non-interactive CI where the prompt is auto-canceled; users intentionally aborting a destroy after seeing which resources will be removed; automation that can't respond to the interactive confirmation.
Related errors
- helm upgrade --install failed with exit code
- Cannot derive a Helm release name from resource name
- Cannot derive a Kubernetes namespace from resource name
- Chart description must be a string or a parameter resource…
- Chart name must be a string or a parameter resource builder.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/68e51eba58ae6d7f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Kubernetes/Deployment/HelmDeploymentEngine.cs:701
}
var result = await interactionService.PromptNotificationAsync(
"Destroy environment",
message,
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.");
}
}
}
private static async Task<List<string>> GetServiceEndpointsAsync(
string serviceName,
string @namespace,
string? kubeConfigPath,
ILogger logger,
CancellationToken cancellationToken)
{
var endpoints = new List<string>();
var arguments = $"get service {serviceName} --namespace {@namespace} -o json";
if (kubeConfigPath is not null)
{
arguments += $" --kubeconfig \"{kubeConfigPath}\"";View on GitHub (pinned to 25830f84bd)