{"record":{"id":"01496f035c5a2e2c","repo":"microsoft/aspire","slug":"options-tier-is-not-a-valid-azure-sandbox-tier","errorCode":null,"errorMessage":"'{options.Tier}' is not a valid Azure sandbox tier.","messagePattern":"'(.+?)' is not a valid Azure sandbox tier\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Azure.Sandboxes/AzureSandboxesExtensions.cs","lineNumber":366,"sourceCode":"        // https://learn.microsoft.com/azure/templates/microsoft.authorization/2022-04-01/roleassignments\n        infrastructure.Add(new RoleAssignment($\"{sandboxGroup.BicepIdentifier}_deploymentPrincipalDataOwner\")\n        {\n            Name = BicepFunction.CreateGuid(\n                sandboxGroup.Id,\n                principalId,\n                BicepFunction.GetSubscriptionResourceId(\"Microsoft.Authorization/roleDefinitions\", SandboxGroupDataOwnerRoleId)),\n            Scope = new IdentifierExpression(sandboxGroup.BicepIdentifier),\n            PrincipalType = principalType,\n            PrincipalId = principalId,\n            RoleDefinitionId = BicepFunction.GetSubscriptionResourceId(\"Microsoft.Authorization/roleDefinitions\", SandboxGroupDataOwnerRoleId)\n        });\n    }\n\n    private static void ValidateSandboxOptions(AzureSandboxOptions options)\n    {\n        if (!Enum.IsDefined(options.Tier))\n        {\n            throw new ArgumentException($\"'{options.Tier}' is not a valid Azure sandbox tier.\", nameof(options));\n        }\n\n        ValidateOptionalWholeSecondDuration(\n            options.AutoSuspendInterval,\n            nameof(AzureSandboxOptions.AutoSuspendInterval),\n            TimeSpan.FromSeconds(int.MaxValue));\n        ValidateOptionalEnum(options.AutoSuspendMode, nameof(AzureSandboxOptions.AutoSuspendMode));\n        ValidateOptionalWholeSecondDuration(options.AutoDeleteInterval, nameof(AzureSandboxOptions.AutoDeleteInterval));\n        ValidateOptionalEnum(options.AutoDeleteTrigger, nameof(AzureSandboxOptions.AutoDeleteTrigger));\n\n        if (options.AutoSuspendEnabled is null &&\n            (options.AutoSuspendInterval is not null || options.AutoSuspendMode is not null))\n        {\n            throw new ArgumentException(\n                $\"{nameof(AzureSandboxOptions.AutoSuspendEnabled)} must be set when configuring auto-suspend interval or mode.\",\n                nameof(options));\n        }\n","sourceCodeStart":348,"sourceCodeEnd":384,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Azure.Sandboxes/AzureSandboxesExtensions.cs#L348-L384","documentation":"AzureSandboxOptions.Tier was validated with Enum.IsDefined and the supplied value is not a defined member of the sandbox tier enum. Because Tier is typed as the enum, this typically occurs when an out-of-range numeric value or a stale/unsupported tier was supplied, and the library refuses it via ArgumentException.","triggerScenarios":"Calling PublishAsAzureSandbox with options whose Tier is an enum value not defined by the current tier enum — e.g. casting an arbitrary int/long to the tier type, deserializing an unrecognized tier string/number from configuration, or using a tier from a different package version.","commonSituations":"Loading sandbox tier from app configuration (appsettings/env) without validating; casting config strings to the enum via (Tier)intValue; a package upgrade/downgrade renaming or removing a tier value that older config still references.","solutions":["Set Tier to one of the enum's defined members (use the enum type directly instead of casting ints).","Validate any externally sourced tier value against Enum.IsDefined(options.Tier) before calling PublishAsAzureSandbox.","Check the package version's tier enum members and update configuration referencing an old or renamed tier."],"exampleFix":"// before\nvar options = new AzureSandboxOptions { Tier = (SandboxTier)configValue };\n\n// after\nvar options = new AzureSandboxOptions\n{\n    Tier = Enum.IsDefined(typeof(SandboxTier), configValue)\n        ? (SandboxTier)configValue\n        : throw new ArgumentException($\"Unknown sandbox tier: {configValue}\")\n};","handlingStrategy":"validation","validationCode":"if (options.Tier is SandboxTier t && !Enum.IsDefined(t))\n{\n    throw new ArgumentException($\"'{options.Tier}' is not a valid Azure sandbox tier.\");\n}","typeGuard":"bool IsValidTier<T>(T value) where T : struct, Enum => Enum.IsDefined(value);","tryCatchPattern":"try { builder.PublishAsAzureSandbox(options); } catch (ArgumentException ex) when (ex.Message.Contains(\"not a valid Azure sandbox tier\")) { /* correct the Tier value or pin the package version */ }","preventionTips":["Never cast raw ints/strings to the tier enum without Enum.IsDefined/Enum.TryParse checks.","Keep tier values in configuration validated at startup.","Check enum members after upgrading or downgrading the package version."],"tags":["azure","sandbox-group","enum","validation","configuration"],"backgroundTag":"invalid-enum-value","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"}