microsoft/aspire · error · ArgumentException

Unsupported channel ' '. Available channels

Error message

Unsupported channel '{channelName}'. Available channels: {string.Join(", ", channels.Select(c => c.Name))}

What it means

DownloadLatestCliAsync looks up channel information from the PackagingService and throws ArgumentException when no channel matches the requested channelName (case-insensitive). The message lists all available channel names so the caller can pick a valid one.

Solutions

  1. Use one of the channel names listed in the error message.
  2. Check the spelling/casing conventions of the intended channel.
  3. Enumerate channels via the PackagingService before downloading to validate the name.
  4. Update scripts to the current channel naming after CLI version changes.

Example fix

// before
await cliDownloader.DownloadLatestCliAsync("stabel", ct);   // typo
// after
await cliDownloader.DownloadLatestCliAsync("stable", ct);
Defensive patterns

Strategy: validation

Validate before calling

var channels = await packagingService.GetChannelsAsync(ct);
if (!channels.Any(c => c.Name.Equals(channelName, StringComparison.OrdinalIgnoreCase)))
{
    throw new ArgumentException($"Unknown channel '{channelName}'. Available: {string.Join(", ", channels.Select(c => c.Name))}");
}

Try / catch

try { await cliDownloader.DownloadLatestCliAsync(channel, ct); }
catch (ArgumentException ex) when (ex.Message.StartsWith("Unsupported channel")) { // list channels and prompt user
}

Prevention

When it happens

Trigger: Calling DownloadLatestCliAsync (or CLI download via channel) with a channelName that is not in the packaging service's channel list — e.g. 'stable' when only 'stable'/'daily'-style named channels exist, or a misspelled name.

Common situations: Typo in the channel name; using an old channel name removed from packaging metadata; scripting with a hardcoded channel that no longer exists.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Cli/Utils/CliDownloader.cs:40

    IEnvironment environment,
    ILogger<CliDownloader> logger,
    IInteractionService interactionService,
    IPackagingService packagingService) : ICliDownloader
{
    private const int ArchiveDownloadTimeoutSeconds = 600;
    private const int ChecksumDownloadTimeoutSeconds = 120;

    private static readonly HttpClient s_httpClient = new();

    public async Task<string> DownloadLatestCliAsync(string channelName, CancellationToken cancellationToken)
    {
        // Get the channel information from PackagingService
        var channels = await packagingService.GetChannelsAsync(cancellationToken, channelName);
        var channel = channels.FirstOrDefault(c => c.Name.Equals(channelName, StringComparison.OrdinalIgnoreCase));

        if (channel is null)
        {
            throw new ArgumentException($"Unsupported channel '{channelName}'. Available channels: {string.Join(", ", channels.Select(c => c.Name))}");
        }

        if (string.IsNullOrEmpty(channel.CliDownloadBaseUrl))
        {
            throw new InvalidOperationException($"Channel '{channelName}' does not support CLI downloads.");
        }

        var baseUrl = channel.CliDownloadBaseUrl.TrimEnd('/');

        var (os, arch) = DetectPlatform();
        var runtimeIdentifier = $"{os}-{arch}";
        var extension = os == "win" ? "zip" : "tar.gz";
        var archiveFilename = $"aspire-cli-{runtimeIdentifier}.{extension}";
        var checksumFilename = $"{archiveFilename}.sha512";
        var archiveUrl = $"{baseUrl}/{archiveFilename}";
        var checksumUrl = $"{baseUrl}/{checksumFilename}";

        // Create temp directory for download

View on GitHub (pinned to 25830f84bd)