microsoft/aspire · error · ArgumentException

Endpoint and repository must both be strings or parameter…

Error message

Endpoint and repository must both be strings or parameter resource builders.

What it means

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).

Solutions

  1. Pass both endpoint and repository as strings, or both as IResourceBuilder<ParameterResource>.
  2. Convert a literal to a parameter (or resolve the parameter to a string) so both arguments match in kind.
  3. Use the underlying AddContainerRegistry overloads directly with a consistent pair of arguments.
  4. exampleFix placeholder

Example fix

// before
builder.AddContainerRegistryForPolyglot("registry", "myacr.azurecr.io", repoParameter);
// after (both as parameters)
var endpoint = builder.AddParameter("registry-endpoint");
builder.AddContainerRegistryForPolyglot("registry", endpoint, repoParameter);
Defensive patterns

Strategy: validation

Validate before calling

bool IsValidRegistryArgs(object? endpoint, object? repository) =>
    (endpoint is string && (repository is null || repository is string)) ||
    (endpoint is IResourceBuilder<ParameterResource> && (repository is null || repository is IResourceBuilder<ParameterResource>));
if (!IsValidRegistryArgs(endpoint, repository)) throw new ArgumentException("Endpoint and repository must both be strings or parameter resource builders.");

Try / catch

try
{
    builder.AddContainerRegistryForPolyglot(name, endpoint, repository);
}
catch (ArgumentException ex)
{
    // Normalize argument kinds and retry
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting/ContainerRegistryResourceBuilderExtensions.cs:141

    internal static IResourceBuilder<ContainerRegistryResource> AddContainerRegistryForPolyglot(
        this IDistributedApplicationBuilder builder,
        [ResourceName] string name,
        [AspireUnion(typeof(string), typeof(IResourceBuilder<ParameterResource>))] object endpoint,
        [AspireUnion(typeof(string), typeof(IResourceBuilder<ParameterResource>))] object? repository = null)
    {
        ArgumentNullException.ThrowIfNull(builder);
        ArgumentException.ThrowIfNullOrEmpty(name);
        ArgumentNullException.ThrowIfNull(endpoint);

        return (endpoint, repository) switch
        {
            (string endpointValue, null) => builder.AddContainerRegistry(name, endpointValue),
            (string endpointValue, string repositoryValue) => builder.AddContainerRegistry(name, endpointValue, repositoryValue),
            (IResourceBuilder<ParameterResource> endpointParameter, null) => builder.AddContainerRegistry(name, endpointParameter),
            (IResourceBuilder<ParameterResource> endpointParameter, IResourceBuilder<ParameterResource> repositoryParameter)
                => builder.AddContainerRegistry(name, endpointParameter, repositoryParameter),
            _ => throw new ArgumentException(
                "Endpoint and repository must both be strings or parameter resource builders.",
                nameof(repository))
        };
    }

    /// <summary>
    /// Subscribes to BeforeStartEvent to add RegistryTargetAnnotation to all resources in the model.
    /// </summary>
    private static void SubscribeToAddRegistryTargetAnnotations(IDistributedApplicationBuilder builder, ContainerRegistryResource registry)
    {
        builder.OnBeforeStart((beforeStartEvent, cancellationToken) =>
        {
            foreach (var resource in beforeStartEvent.Model.Resources)
            {
                // Add a RegistryTargetAnnotation to indicate this registry is available as a default target
                resource.Annotations.Add(new RegistryTargetAnnotation(registry));
            }

            return Task.CompletedTask;

View on GitHub (pinned to 25830f84bd)