{"record":{"id":"9aa63beede5ef6ad","repo":"microsoft/aspire","slug":"aspireradius049","errorCode":"ASPIRERADIUS049","errorMessage":"Secret-store name '{name}' is invalid. It must be 1-{RadiusSecretStoreNaming.MaxNameLength} characters of lowercase ASCII letters, digits, and '-', must start with a letter, may not contain consecutive hyphens, may not end with a hyphen, and may not be a reserved device name. Diagnostic: ASPIRERADIUS049.","messagePattern":"Secret-store name '(.+?)' is invalid\\. It must be 1-(.+?) characters of lowercase ASCII letters, digits, and '-', must start with a letter, may not contain consecutive hyphens, may not end with a hyphen, and may not be a reserved device name\\. Diagnostic: ASPIRERADIUS049\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Radius/Secrets/RadiusSecretStoreExtensions.cs","lineNumber":387,"sourceCode":"    [Experimental(\"ASPIRERADIUS006\", UrlFormat = \"https://aka.ms/aspire/diagnostics/{0}\")]\n    private static void EnsureNotAlreadyPopulated(RadiusSecretStoreResource store)\n    {\n        if (store.Population.IsPopulated)\n        {\n            throw new InvalidOperationException(\n                $\"Secret store '{store.Name}' already declares a population mode; declare exactly one of \" +\n                \"WithData, WithExistingSecret, or WithSealedSecret, once. Diagnostic: ASPIRERADIUS065.\");\n        }\n    }\n\n    // The store name is used verbatim as a Bicep symbol/resource name, a UCP-ID segment,\n    // and a Radius-created Secret name, so it must be a valid single resource-name segment.\n    private static void ValidateStoreName([NotNull] string? name)\n    {\n        ArgumentException.ThrowIfNullOrWhiteSpace(name);\n        if (!RadiusSecretStoreNaming.IsValidName(name))\n        {\n            throw new ArgumentException(\n                $\"Secret-store name '{name}' is invalid. It must be 1-{RadiusSecretStoreNaming.MaxNameLength} characters of \" +\n                \"lowercase ASCII letters, digits, and '-', must start with a letter, may not contain consecutive hyphens, may \" +\n                \"not end with a hyphen, and may not be a reserved device name. Diagnostic: ASPIRERADIUS049.\",\n                nameof(name));\n        }\n    }\n}\n\n/// <summary>\n/// Builds the inline <c>data</c> map for a secret store declared with <c>WithData(...)</c>.\n/// </summary>\n[Experimental(\"ASPIRERADIUS006\", UrlFormat = \"https://aka.ms/aspire/diagnostics/{0}\")]\npublic sealed class RadiusSecretStoreDataBuilder\n{\n    private readonly RadiusSecretStorePopulation _population;\n\n    internal RadiusSecretStoreDataBuilder(RadiusSecretStorePopulation population) => _population = population;\n","sourceCodeStart":369,"sourceCodeEnd":405,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Radius/Secrets/RadiusSecretStoreExtensions.cs#L369-L405","documentation":"AddRadiusSecretStore/WithSecretStore validates the secret-store name via ValidateStoreName because the name becomes a Kubernetes single resource-name segment. RadiusSecretStoreNaming.IsValidName requires 1-64 chars of lowercase ASCII letters, digits and '-', starting with a letter, no consecutive hyphens, no trailing hyphen, and not a reserved device name. Throwing at the API boundary avoids a failure only at cluster-apply time.","triggerScenarios":"Calling AddRadiusSecretStore(name, ...) or WithSecretStore(name) with a null/whitespace name, an empty string, uppercase letters, underscores, a leading digit or hyphen, '--', a trailing '-', or names like 'CON'/'PRN'.","commonSituations":"Deriving the store name from a C# identifier or parameter name that contains underscores or uppercase; building a name by concatenation that leaves a trailing hyphen; reusing Windows device names.","solutions":["Rename the secret store to a lowercase alphanumeric string starting with a letter, using single '-' separators (e.g. 'my-store-key').","If the name comes from another identifier, normalize it (lowercase, replace '_' with '-', collapse and trim hyphens) before passing it in.","Check the length is within RadiusSecretStoreNaming.MaxNameLength and shorten if needed."],"exampleFix":"// before\nbuilder.AddRadiusSecretStore(\"My_SecretStore-\");\n// after\nbuilder.AddRadiusSecretStore(\"my-secretstore\");","handlingStrategy":"validation","validationCode":"static bool IsValidStoreName(string? name) =>\n    !string.IsNullOrWhiteSpace(name) && name.Length <= RadiusSecretStoreNaming.MaxNameLength &&\n    RadiusSecretStoreNaming.IsValidName(name);","typeGuard":null,"tryCatchPattern":"try { builder.AddRadiusSecretStore(name, ...); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"ASPIRERADIUS049\")) { /* normalize name and retry */ }","preventionTips":["Generate store names with a slug helper: lowercase, replace non [a-z0-9-], collapse hyphens, trim '-', ensure starts with a letter","Avoid deriving names from Windows identifiers or device names","Add a unit test asserting your name-generation output against RadiusSecretStoreNaming.IsValidName"],"tags":["validation","naming","radius"],"backgroundTag":"invalid-identifier-format","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"}