microsoft/aspire · error · InvalidOperationException

ASPIRERADIUS065

ASPIRERADIUS065

Error message

Secret store '{store.Name}' already declares a population mode; declare exactly one of WithData, WithExistingSecret, or WithSealedSecret, once. Diagnostic: ASPIRERADIUS065.

What it means

A Radius secret store must declare exactly one population mode: WithData, WithExistingSecret, or WithSealedSecret. EnsureNotAlreadyPopulated checks store.Population.IsPopulated and throws if a second population call is made, preventing silently appended keys across modes or manifests.

Solutions

  1. Keep exactly one population call per store — remove the redundant one
  2. Split into two separate secret stores if both data sources are needed
  3. Move the population call into a single shared code path
  4. If mode is chosen at runtime, call only one branch

Example fix

// before
var store = builder.AddRadiusSecretStore("creds")
    .WithData("key1", v1)
    .WithExistingSecret("team/creds");
// after
var store = builder.AddRadiusSecretStore("creds")
    .WithExistingSecret("team/creds");
Defensive patterns

Strategy: validation

Validate before calling

var populated = store.Population.IsPopulated; if (populated) throw new InvalidOperationException("Store already declares a population mode.");

Try / catch

try { store.WithSealedSecret(...); } catch (InvalidOperationException ex) when (ex.Message.Contains("ASPIRERADIUS065")) { logger.LogError(ex, "Duplicate population mode on store '{Store}'", store.Name); throw; }

Prevention

When it happens

Trigger: Chaining two population calls on the same store, e.g. WithData(...).WithExistingSecret(...), or calling WithSealedSecret on a store that already declares a mode; conditional code paths that both may populate the store.

Common situations: Fluent chains copied from examples combining data keys with an existing secret; refactoring where a new population call was added without removing the old one; helper methods that each call a population API unconditionally.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/e73bb2667ac37db8. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Radius/Secrets/RadiusSecretStoreExtensions.cs:374

            throw new ArgumentException(
                $"Existing-secret reference '{namespaceAndName}' is invalid. The name must be a DNS-1123 subdomain and " +
                "the optional namespace a DNS-1123 label (lowercase alphanumeric, '-', with '.' allowed in the name). " +
                "Diagnostic: ASPIRERADIUS046.",
                nameof(namespaceAndName));
        }

        return namespaceAndName;
    }

    // A secret store must declare exactly one population mode. Reject a second population call
    // (repeated same-mode or cross-mode) at the call site so misuse fails immediately with a clear
    // stack trace, rather than silently appending keys across modes/manifests or reaching the gate.
    [Experimental("ASPIRERADIUS006", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
    private static void EnsureNotAlreadyPopulated(RadiusSecretStoreResource store)
    {
        if (store.Population.IsPopulated)
        {
            throw new InvalidOperationException(
                $"Secret store '{store.Name}' already declares a population mode; declare exactly one of " +
                "WithData, WithExistingSecret, or WithSealedSecret, once. Diagnostic: ASPIRERADIUS065.");
        }
    }

    // The store name is used verbatim as a Bicep symbol/resource name, a UCP-ID segment,
    // and a Radius-created Secret name, so it must be a valid single resource-name segment.
    private static void ValidateStoreName([NotNull] string? name)
    {
        ArgumentException.ThrowIfNullOrWhiteSpace(name);
        if (!RadiusSecretStoreNaming.IsValidName(name))
        {
            throw new ArgumentException(
                $"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.",
                nameof(name));
        }

View on GitHub (pinned to 25830f84bd)