microsoft/aspire · error · ArgumentException
A purge task with the name
Error message
A purge task with the name '{taskName}' already exists. What it means
WithPurgeTask checks existing ACR tasks on the registry resource and throws ArgumentException when an explicitly supplied taskName collides with an existing task name (ordinal comparison). Auto-generated names use a numeric suffix to avoid collisions.
Solutions
- Use a unique taskName per WithPurgeTask call
- Omit taskName so the method auto-generates a suffixed name
- Rename or remove the pre-existing ACR task with the same name
Example fix
// before .WithPurgeTask(taskName: "purge", schedule: "0 3 * * *", keep: 10) .WithPurgeTask(taskName: "purge", schedule: "0 4 * * *", keep: 5) // after .WithPurgeTask(taskName: "purge-nightly", schedule: "0 3 * * *", keep: 10) .WithPurgeTask(taskName: "purge-weekly", schedule: "0 4 * * 0", keep: 5)
Defensive patterns
Strategy: validation
Validate before calling
var nameInUse = registryResource.Infrastructure
.GetResources().OfType<ContainerRegistryTask>()
.Any(t => string.Equals(t.Name.Value, taskName, StringComparison.Ordinal)); Try / catch
try { env.WithPurgeTask(taskName: taskName, schedule: cron, keep: 10); }
catch (ArgumentException ex) when (ex.Message.Contains("already exists")) { log.LogError(ex, "Duplicate task name {Task}", taskName); } Prevention
- Let WithPurgeTask auto-name tasks when uniqueness is hard to guarantee
- Keep a registry of task names used in the app model
- Check for pre-existing tasks in imported infrastructure
When it happens
Trigger: Calling WithPurgeTask twice with the same explicit taskName, or with a taskName that matches a task created elsewhere (another WithPurgeTask call, ARM/Bicep-defined task).
Common situations: Adding multiple purge schedules in a loop that reuses a constant name; a name collision with pre-existing infrastructure in the same Bicep module.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- Access policy ' ' is already registered on connector…
- Access policy resource
- Access policy resource
- Ago must be at least 1 minute to be compatible with acr…
- An access policy for principal
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/839f8cac60c3633a.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Azure.ContainerRegistry/AzureContainerRegistryExtensions.cs:202
return builder.ConfigureInfrastructure(infra =>
{
var prefix = "purgeOldImages";
var registry = infra.GetProvisionableResources().OfType<ContainerRegistryService>().Single();
var allTasks = infra.GetProvisionableResources().OfType<ContainerRegistryTask>()
.Where(t => t.Parent == registry)
.ToList();
var autoNamedTasks = allTasks
.Where(t => t.Name.Value?.StartsWith(prefix, StringComparison.Ordinal) == true)
.ToList();
var taskIndex = autoNamedTasks.Count;
if (!string.IsNullOrWhiteSpace(taskName))
{
if (allTasks.Any(t => string.Equals(t.Name.Value, taskName, StringComparison.Ordinal)))
{
throw new ArgumentException($"A purge task with the name '{taskName}' already exists.", nameof(taskName));
}
}
else
{
taskName = taskIndex == 0 ? prefix : $"{prefix}_{taskIndex}";
}
var bicepIdentifier = $"{prefix}_{taskIndex}";
var purgeTaskCmdVariable = new ProvisioningVariable($"purgeTaskCmd_{taskIndex}", typeof(string))
{
Value = CreatePurgeTaskContent(filter, purgeAgo, keep)
};
infra.Add(purgeTaskCmdVariable);
var purgeTask = new ContainerRegistryTask(bicepIdentifier)
{
Name = taskName,View on GitHub (pinned to 25830f84bd)