{"record":{"id":"0e43a131f4fe6cc6","repo":"microsoft/aspire","slug":"resource-targetresource-name-maps-multiple-distinct","errorCode":null,"errorMessage":"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.","messagePattern":"Resource '(.+?)' maps multiple distinct (.+?) sources named '(.+?)' to Helm values path '(.+?)\\.(.+?)\\.(.+?)'\\. Reuse the same ParameterResource instance or give each source a unique name\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Kubernetes/KubernetesResource.cs","lineNumber":741,"sourceCode":"        ParameterResource parameter,\n        HelmValue helmValue,\n        string helmKey,\n        string sourceKind)\n    {\n        if (!mappings.TryGetValue(parameter.Name, out var existing))\n        {\n            mappings.Add(parameter.Name, helmValue);\n            return;\n        }\n\n        if (ReferenceEquals(existing.ParameterSource, parameter))\n        {\n            return;\n        }\n\n        var resourceKey = TargetResource.Name.ToHelmValuesSectionName();\n        var valuesKey = helmValue.ValuesKey ?? parameter.Name.ToHelmValuesSectionName();\n        throw new InvalidOperationException(\n            $\"Resource '{TargetResource.Name}' maps multiple distinct {sourceKind} sources named '{parameter.Name}' \" +\n            $\"to Helm values path '{helmKey}.{resourceKey}.{valuesKey}'. Reuse the same ParameterResource instance \" +\n            \"or give each source a unique name.\");\n    }\n\n    private static string GetEndpointValue(EndpointMapping mapping, EndpointProperty property, bool embedded = false)\n    {\n        var (scheme, _, host, targetPort, _, _, exposedPort) = mapping;\n\n        // In Kubernetes a Service publishes `port` and forwards traffic to the pod's `targetPort`.\n        // Other resources reach this resource through the Service, so the client-facing address must\n        // use the Service (exposed) port, not the container's listening port. When no distinct\n        // exposed port was configured (`port == targetPort`, or the deployment tool assigns it),\n        // ServicePort is null and we fall back to the target port. Only EndpointProperty.TargetPort\n        // surfaces the container's listening port. This mirrors the Azure Container Apps publisher.\n        // See: https://github.com/microsoft/aspire/issues/18321\n        var servicePort = exposedPort ?? targetPort;\n","sourceCodeStart":723,"sourceCodeEnd":759,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Kubernetes/KubernetesResource.cs#L723-L759","documentation":"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.","triggerScenarios":"BuildHelmConditional or AllocateAdditionalParameter registering a second, non-identical ParameterResource whose name (or ValuesKey) collides with a previously mapped parameter for the same target resource.","commonSituations":"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.","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"],"exampleFix":"// before\nvar p1 = builder.AddParameter(\"conn\");\nvar p2 = builder.AddParameter(\"conn\"); // distinct instance, same name\nresource.WithReference(expr1(p1));\nresource.WithReference(expr2(p2));\n// after\nvar p = builder.AddParameter(\"conn\");\nresource.WithReference(expr1(p));\nresource.WithReference(expr2(p)); // reuse the same instance","handlingStrategy":"validation","validationCode":"var dupes = parameters.GroupBy(p => p.Name).Where(g => g.Count() > 1 && g.Select(x => x).Distinct().Count() > 1).ToList();\nif (dupes.Any()) throw new InvalidOperationException($\"Distinct parameters share names: {string.Join(\",\", dupes.Select(d => d.Key))}\");","typeGuard":null,"tryCatchPattern":"try { PublishAsync(...); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"maps multiple distinct\")) { /* deduplicate parameter instances */ }","preventionTips":["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"],"tags":["kubernetes","helm","parameters","naming-collision"],"backgroundTag":"conflicting-config-options","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"}