microsoft/aspire · error · InvalidOperationException
Resource ' ' maps multiple distinct sources named ' ' to…
Error message
Resource '{TargetResource.Name}' maps multiple distinct {sourceKind} sources named '{parameter.Name}' to Helm values path '{helmKey}.{resourceKey}.{valuesKey}'. Reuse the same ParameterResource instance or give each source a unique name. What it means
Thrown by AddParameterMapping in KubernetesResource when two distinct ParameterResource instances with the same name would map to the same Helm values path '{helmKey}.{resourceKey}.{valuesKey}'. The publisher requires that each Helm values path is backed by exactly one parameter instance so conditional/expression resolution is deterministic.
Solutions
- Reuse the same ParameterResource instance everywhere instead of creating a second one with the same name
- Give each distinct source a unique parameter name
- Set an explicit unique ValuesKey on the Helm value mapping for one of the sources
- Search the app model for duplicate AddParameter calls with the colliding name
Example fix
// before
var p1 = builder.AddParameter("conn");
var p2 = builder.AddParameter("conn"); // distinct instance, same name
resource.WithReference(expr1(p1));
resource.WithReference(expr2(p2));
// after
var p = builder.AddParameter("conn");
resource.WithReference(expr1(p));
resource.WithReference(expr2(p)); // reuse the same instance Defensive patterns
Strategy: validation
Validate before calling
var dupes = parameters.GroupBy(p => p.Name).Where(g => g.Count() > 1 && g.Select(x => x).Distinct().Count() > 1).ToList();
if (dupes.Any()) throw new InvalidOperationException($"Distinct parameters share names: {string.Join(",", dupes.Select(d => d.Key))}"); Try / catch
try { PublishAsync(...); }
catch (InvalidOperationException ex) when (ex.Message.Contains("maps multiple distinct")) { /* deduplicate parameter instances */ } Prevention
- Create each parameter once and share the instance
- Never create two AddParameter calls with the same name
- Set explicit unique ValuesKeys for conditionally-generated parameters
When it happens
Trigger: BuildHelmConditional or AllocateAdditionalParameter registering a second, non-identical ParameterResource whose name (or ValuesKey) collides with a previously mapped parameter for the same target resource.
Common situations: Creating two separate builder.AddParameter("name") calls in different places with the same name and passing both into expressions; deserialization or cloning producing distinct ParameterResource instances that share a name; conditional expressions pulling in a same-named parameter from a different resource.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Resource ' ' maps both and to Helm values path ' . . '…
- Cannot derive a Helm release name from resource name
- Cannot derive a Kubernetes namespace from resource name
- Chart description must be a string or a parameter resource…
- Chart name must be a string or a parameter resource builder.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/0e43a131f4fe6cc6.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Kubernetes/KubernetesResource.cs:741
ParameterResource parameter,
HelmValue helmValue,
string helmKey,
string sourceKind)
{
if (!mappings.TryGetValue(parameter.Name, out var existing))
{
mappings.Add(parameter.Name, helmValue);
return;
}
if (ReferenceEquals(existing.ParameterSource, parameter))
{
return;
}
var resourceKey = TargetResource.Name.ToHelmValuesSectionName();
var valuesKey = helmValue.ValuesKey ?? parameter.Name.ToHelmValuesSectionName();
throw new InvalidOperationException(
$"Resource '{TargetResource.Name}' maps multiple distinct {sourceKind} sources named '{parameter.Name}' " +
$"to Helm values path '{helmKey}.{resourceKey}.{valuesKey}'. Reuse the same ParameterResource instance " +
"or give each source a unique name.");
}
private static string GetEndpointValue(EndpointMapping mapping, EndpointProperty property, bool embedded = false)
{
var (scheme, _, host, targetPort, _, _, exposedPort) = mapping;
// In Kubernetes a Service publishes `port` and forwards traffic to the pod's `targetPort`.
// Other resources reach this resource through the Service, so the client-facing address must
// use the Service (exposed) port, not the container's listening port. When no distinct
// exposed port was configured (`port == targetPort`, or the deployment tool assigns it),
// ServicePort is null and we fall back to the target port. Only EndpointProperty.TargetPort
// surfaces the container's listening port. This mirrors the Azure Container Apps publisher.
// See: https://github.com/microsoft/aspire/issues/18321
var servicePort = exposedPort ?? targetPort;
View on GitHub (pinned to 25830f84bd)