microsoft/aspire · error · InvalidOperationException
ASPIRERADIUS087
ASPIRERADIUS087
Error message
A ConfigureRadiusInfrastructure callback left environment variable '{key}' on container '{container.ContainerMapKey}' with neither a 'value' nor a 'valueFrom.secretKeyRef'. The variable would be dropped from the deployed container. Assign either Value or the SecretName/SecretKey pair. Diagnostic: ASPIRERADIUS087. What it means
RadiusInfrastructureBuilder validates each environment variable on a Radius container and throws when an entry is null or its Value is unset with no usable value. An env var with neither a literal value nor a secret reference would simply be dropped from the deployed container, so the builder surfaces the problem at publish time instead. This is the guard for entries left as holes (e.g. by assigning null through the BicepDictionary wrapper).
Solutions
- Assign a Value to the environment variable entry, or set its SecretName/SecretKey pair
- If the variable was meant to be removed, delete the entry entirely rather than assigning null
- Remove the callback line that created the empty entry
Example fix
// before
container.Env["FEATURE_FLAG"] = null;
// after
container.Env["FEATURE_FLAG"] = new() { Value = "true" }; Defensive patterns
Strategy: validation
Validate before calling
if (container.Env[key]?.Value is null)
throw new InvalidOperationException($"Env var '{key}' needs a Value or SecretName/SecretKey."); Type guard
static bool HasUsableEntry(BicepDictionary<RadiusEnvValue>.Entry? e) => e?.Value is not null;
Try / catch
try { /* publish */ }
catch (InvalidOperationException ex) when (ex.Message.Contains("ASPIRERADIUS087"))
{
// fix the env entry or drop it entirely
} Prevention
- Never assign null to an env var entry to 'clear' it — remove the entry instead
- Only add env entries once the value or secret reference is known
- Search callbacks for assignments that may be conditional/no-op
When it happens
Trigger: A ConfigureRadiusInfrastructure callback leaves container.Env[key] null, or the BicepDictionary entry has no Value — detected when entry?.Value is not { } envVar. Diagnostic code ASPIRERADIUS087.
Common situations: Assigning null to an env var in a callback intending to 'clear' it, or constructing an environment entry but forgetting to set Value before publishing.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- ASPIRERADIUS093
- A ConfigureRadiusInfrastructure callback changed port
- A ConfigureRadiusInfrastructure callback left container
- A ConfigureRadiusInfrastructure callback replaced port
- A ConfigureRadiusInfrastructure callback replaced the…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/696c35e73f8bca18.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Radius/Publishing/RadiusInfrastructureBuilder.cs:5097
/// a rejected manifest at <c>rad deploy</c> time.
/// </para>
/// <para>
/// Assignment is detected with <see cref="RenderBicepValue"/> rather than a null check on the
/// property: <c>DefineProperty</c> returns a non-null <see cref="BicepValue{T}"/> in an unset
/// state, so an unassigned property is only recognisable by having neither an expression nor a
/// literal — the same test <c>ProjectedEnvValue.OriginalValue</c> relies on.
/// </para>
/// </remarks>
private static void ValidateContainerEnvVarForms(RadiusInfrastructureOptions options)
{
foreach (var container in options.Containers)
{
foreach (var (key, entry) in container.Env)
{
// BicepDictionary wraps each entry; a callback can leave a hole by assigning null.
if (entry?.Value is not { } envVar)
{
throw new InvalidOperationException(
$"A ConfigureRadiusInfrastructure callback left environment variable '{key}' on container " +
$"'{container.ContainerMapKey}' with neither a 'value' nor a 'valueFrom.secretKeyRef'. The " +
$"variable would be dropped from the deployed container. Assign either Value or the " +
$"SecretName/SecretKey pair. Diagnostic: ASPIRERADIUS087.");
}
var hasValue = RenderBicepValue(envVar.Value) is not null;
var hasSecretName = RenderBicepValue(envVar.SecretName) is not null;
var hasSecretKey = RenderBicepValue(envVar.SecretKey) is not null;
// Neither form assigned. Radius accepts the empty object and the Kubernetes recipe
// emits no `value` and no `valueFrom`, so the variable the callback added is absent
// from the deployed container — the same silent drop the two checks below exist to
// prevent, reached by leaving everything unset rather than by setting too much.
if (!hasValue && !hasSecretName && !hasSecretKey)
{
throw new InvalidOperationException(
$"A ConfigureRadiusInfrastructure callback left environment variable '{key}' on container " +View on GitHub (pinned to 25830f84bd)