microsoft/aspire · error · ArgumentException
' ' is not a valid AzureContainerRegistryRole value.
Error message
'{roles[i]}' is not a valid AzureContainerRegistryRole value. What it means
WithRoleAssignments maps each AzureContainerRegistryRole enum value to an Azure Provisioning ContainerRegistryBuiltInRole; the switch's default arm throws ArgumentException naming the offending element when the roles array contains an undefined/out-of-range enum value.
Solutions
- Pass only valid AzureContainerRegistryRole members (AcrPull, AcrPush, AcrDelete, AcrImageSigner, AcrQuarantineReader/Writer, etc.)
- Validate with Enum.IsName/Enum.IsDefined before building the array
- Fix the config or deserialization mapping that produced the bogus value
Example fix
// before
var role = (AzureContainerRegistryRole)999;
.WithRoleAssignments(target, new[] { role })
// after
if (!Enum.IsDefined(role)) throw new InvalidOperationException($"Unknown role {role}");
.WithRoleAssignments(target, new[] { AzureContainerRegistryRole.AcrPull }) Defensive patterns
Strategy: validation
Validate before calling
foreach (var role in roles)
if (!Enum.IsDefined(typeof(AzureContainerRegistryRole), role))
throw new ArgumentException($"'{role}' is not a valid {nameof(AzureContainerRegistryRole)} value."); Type guard
bool IsValidRole(AzureContainerRegistryRole role) => Enum.IsDefined(typeof(AzureContainerRegistryRole), role);
Try / catch
try { env.WithRoleAssignments(target, roles); }
catch (ArgumentException ex) when (ex.ParamName == "roles") { log.LogError(ex, "Invalid role value"); } Prevention
- Never cast raw ints to enums without Enum.IsDefined
- Parse role names with Enum.TryParse<AzureContainerRegistryRole> (ignoreCase)
- Re-validate role sets after dependency version changes
When it happens
Trigger: Passing an enum value not defined by AzureContainerRegistryRole (e.g. an invalid cast of an int) in the roles argument of WithRoleAssignments.
Common situations: Casting raw ints from config into the enum without validation; deserializing a role name that doesn't match any member; a stale enum value after a package version change.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid Azure AI Search role
- Role ' ' at index is not a valid AzureAppConfigurationRole…
- ' ' is not a valid AzureKeyVaultRole value.
- ' ' is not a valid value.
- ' ' is not a valid value.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/b2038ee50609a54c.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Azure.ContainerRegistry/AzureContainerRegistryExtensions.cs:299
where T : IResource
{
if (roles is null || roles.Length == 0)
{
return builder.WithRoleAssignments(target, Array.Empty<ContainerRegistryBuiltInRole>());
}
var builtInRoles = new ContainerRegistryBuiltInRole[roles.Length];
for (var i = 0; i < roles.Length; i++)
{
builtInRoles[i] = roles[i] switch
{
AzureContainerRegistryRole.AcrDelete => ContainerRegistryBuiltInRole.AcrDelete,
AzureContainerRegistryRole.AcrImageSigner => ContainerRegistryBuiltInRole.AcrImageSigner,
AzureContainerRegistryRole.AcrPull => ContainerRegistryBuiltInRole.AcrPull,
AzureContainerRegistryRole.AcrPush => ContainerRegistryBuiltInRole.AcrPush,
AzureContainerRegistryRole.AcrQuarantineReader => ContainerRegistryBuiltInRole.AcrQuarantineReader,
AzureContainerRegistryRole.AcrQuarantineWriter => ContainerRegistryBuiltInRole.AcrQuarantineWriter,
_ => throw new ArgumentException($"'{roles[i]}' is not a valid {nameof(AzureContainerRegistryRole)} value.", nameof(roles))
};
}
return builder.WithRoleAssignments(target, builtInRoles);
}
private static string CreatePurgeTaskContent(string? filter, string ago, int keep)
{
return $"""
version: v1.1.0
steps:
- cmd: acr purge --filter '{filter ?? ".*:.*"}' --ago {ago} --keep {keep}
""".ReplaceLineEndings("\n");
}
/// <summary>
/// Formats a <see cref="TimeSpan"/> into a Go-style duration string compatible with <c>acr purge --ago</c>.
/// Valid units: <c>d</c> (days), <c>h</c> (hours), <c>m</c> (minutes).View on GitHub (pinned to 25830f84bd)