{"record":{"id":"83989fd1e96b978b","repo":"microsoft/aspire","slug":"endpoint-and-repository-must-both-be-strings-or-parameter","errorCode":null,"errorMessage":"Endpoint and repository must both be strings or parameter resource builders.","messagePattern":"Endpoint and repository must both be strings or parameter resource builders\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/ContainerRegistryResourceBuilderExtensions.cs","lineNumber":141,"sourceCode":"    internal static IResourceBuilder<ContainerRegistryResource> AddContainerRegistryForPolyglot(\n        this IDistributedApplicationBuilder builder,\n        [ResourceName] string name,\n        [AspireUnion(typeof(string), typeof(IResourceBuilder<ParameterResource>))] object endpoint,\n        [AspireUnion(typeof(string), typeof(IResourceBuilder<ParameterResource>))] object? repository = null)\n    {\n        ArgumentNullException.ThrowIfNull(builder);\n        ArgumentException.ThrowIfNullOrEmpty(name);\n        ArgumentNullException.ThrowIfNull(endpoint);\n\n        return (endpoint, repository) switch\n        {\n            (string endpointValue, null) => builder.AddContainerRegistry(name, endpointValue),\n            (string endpointValue, string repositoryValue) => builder.AddContainerRegistry(name, endpointValue, repositoryValue),\n            (IResourceBuilder<ParameterResource> endpointParameter, null) => builder.AddContainerRegistry(name, endpointParameter),\n            (IResourceBuilder<ParameterResource> endpointParameter, IResourceBuilder<ParameterResource> repositoryParameter)\n                => builder.AddContainerRegistry(name, endpointParameter, repositoryParameter),\n            _ => throw new ArgumentException(\n                \"Endpoint and repository must both be strings or parameter resource builders.\",\n                nameof(repository))\n        };\n    }\n\n    /// <summary>\n    /// Subscribes to BeforeStartEvent to add RegistryTargetAnnotation to all resources in the model.\n    /// </summary>\n    private static void SubscribeToAddRegistryTargetAnnotations(IDistributedApplicationBuilder builder, ContainerRegistryResource registry)\n    {\n        builder.OnBeforeStart((beforeStartEvent, cancellationToken) =>\n        {\n            foreach (var resource in beforeStartEvent.Model.Resources)\n            {\n                // Add a RegistryTargetAnnotation to indicate this registry is available as a default target\n                resource.Annotations.Add(new RegistryTargetAnnotation(registry));\n            }\n\n            return Task.CompletedTask;","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/ContainerRegistryResourceBuilderExtensions.cs#L123-L159","documentation":"AddContainerRegistryForPolyglot accepts endpoint/repository as either plain strings or IResourceBuilder<ParameterResource>, and they must be consistent in kind. This ArgumentException is thrown when the combination falls outside the supported patterns (e.g. a string endpoint with a parameter repository).","triggerScenarios":"Calling AddContainerRegistryForPolyglot with a mixed combination such as string endpoint + parameter-resource repository, or an unsupported type for either parameter (e.g. null endpoint with a non-string, non-parameter repository).","commonSituations":"Polyglot (non-.NET) apphost code passing one value as a literal and the other as a parameter reference; dynamic code generators emitting mismatched argument kinds.","solutions":["Pass both endpoint and repository as strings, or both as IResourceBuilder<ParameterResource>.","Convert a literal to a parameter (or resolve the parameter to a string) so both arguments match in kind.","Use the underlying AddContainerRegistry overloads directly with a consistent pair of arguments.","exampleFix placeholder"],"exampleFix":"// before\nbuilder.AddContainerRegistryForPolyglot(\"registry\", \"myacr.azurecr.io\", repoParameter);\n// after (both as parameters)\nvar endpoint = builder.AddParameter(\"registry-endpoint\");\nbuilder.AddContainerRegistryForPolyglot(\"registry\", endpoint, repoParameter);","handlingStrategy":"validation","validationCode":"bool IsValidRegistryArgs(object? endpoint, object? repository) =>\n    (endpoint is string && (repository is null || repository is string)) ||\n    (endpoint is IResourceBuilder<ParameterResource> && (repository is null || repository is IResourceBuilder<ParameterResource>));\nif (!IsValidRegistryArgs(endpoint, repository)) throw new ArgumentException(\"Endpoint and repository must both be strings or parameter resource builders.\");","typeGuard":null,"tryCatchPattern":"try\n{\n    builder.AddContainerRegistryForPolyglot(name, endpoint, repository);\n}\ncatch (ArgumentException ex)\n{\n    // Normalize argument kinds and retry\n}","preventionTips":["Always pass endpoint and repository in the same form (both strings or both parameter builders).","In dynamic-language hosts, check argument types before crossing the boundary.","Prefer parameters for both values when either value is environment-specific."],"tags":["container-registry","arguments","polyglot","aspire"],"backgroundTag":"type-mismatch","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"}