microsoft/aspire · error · ArgumentException

Unsupported provider. Supported providers are 'microsoft'…

Error message

Unsupported provider. Supported providers are 'microsoft' and 'github'.

What it means

UserLoginAsync accepts a LoginProvider enum/constant and only supports Microsoft and GitHub. Any other value hits the switch's default arm and throws ArgumentException naming the offending `provider` argument.

Solutions

  1. Pass LoginProvider.Microsoft or LoginProvider.GitHub explicitly
  2. If the provider comes from config, map/parse it and validate against the two supported values before calling
  3. Check the LoginProvider type for the correct member names in your package version

Example fix

// before
await client.UserLoginAsync((LoginProvider)5, logger); // throws
// after
var provider = LoginProvider.GitHub; // or LoginProvider.Microsoft
await client.UserLoginAsync(provider, logger);
Defensive patterns

Strategy: validation

Validate before calling

if (provider is not (LoginProvider.Microsoft or LoginProvider.GitHub))
    throw new ArgumentException($"Provider must be Microsoft or GitHub, got {provider}", nameof(provider));

Type guard

static bool IsSupportedProvider(LoginProvider p) => p is LoginProvider.Microsoft or LoginProvider.GitHub;

Prevention

When it happens

Trigger: Calling UserLoginAsync with a LoginProvider value other than LoginProvider.Microsoft or LoginProvider.GitHub — e.g. a casted integer, a custom constant, or a provider added in a newer CLI but not yet mapped here.

Common situations: Reading the provider from configuration where the string isn't mapped correctly to the enum; passing default(LoginProvider) which may not equal a supported member.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.DevTunnels/DevTunnelCliClient.cs:278

    }

    public async Task<UserLoginStatus> GetUserLoginStatusAsync(ILogger? logger = default, CancellationToken cancellationToken = default)
    {
        logger?.LogTrace("Getting dev tunnel user login status.");
        var (login, exitCode, error) = await CallCliAsJsonAsync<UserLoginStatus>(
            _cli.UserStatusAsync,
            logger, cancellationToken).ConfigureAwait(false);
        return login ?? throw new DistributedApplicationException($"Failed to get user login status. Exit code {exitCode}: {error}");
    }

    public async Task<UserLoginStatus> UserLoginAsync(LoginProvider provider, ILogger? logger = default, CancellationToken cancellationToken = default)
    {
        logger?.LogTrace("Logging in to dev tunnel service using {LoginProvider}.", provider);
        var exitCode = provider switch
        {
            LoginProvider.Microsoft => await _cli.UserLoginMicrosoftAsync(logger, cancellationToken).ConfigureAwait(false),
            LoginProvider.GitHub => await _cli.UserLoginGitHubAsync(logger, cancellationToken).ConfigureAwait(false),
            _ => throw new ArgumentException("Unsupported provider. Supported providers are 'microsoft' and 'github'.", nameof(provider)),
        };

        if (exitCode == 0)
        {
            // Login succeeded, get the login status
            return await GetUserLoginStatusAsync(logger, cancellationToken).ConfigureAwait(false);
        }

        throw new DistributedApplicationException($"Failed to perform user login. Process finished with exit code: {exitCode}");
    }

    private async Task<(T? Result, int ExitCode, string? Error)> CallCliAsJsonAsync<T>(Func<TextWriter, TextWriter, ILogger?, CancellationToken, Task<int>> cliCall, ILogger? logger = default, CancellationToken cancellationToken = default)
    {
        return await CallCliAsJsonAsync<T>(cliCall, propertyName: null, logger, cancellationToken).ConfigureAwait(false);
    }

    private async Task<(T? Result, int ExitCode, string? Error)> CallCliAsJsonAsync<T>(Func<TextWriter, TextWriter, ILogger?, CancellationToken, Task<int>> cliCall, string? propertyName, ILogger? logger = default, CancellationToken cancellationToken = default)
    {

View on GitHub (pinned to 25830f84bd)