{"record":{"id":"4a0b76a88a12a803","repo":"microsoft/aspire","slug":"unsupported-channel-channelname-available-channels-string","errorCode":null,"errorMessage":"Unsupported channel '{channelName}'. Available channels: {string.Join(\", \", channels.Select(c => c.Name))}","messagePattern":"Unsupported channel '(.+?)'\\. Available channels: (.+?)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Cli/Utils/CliDownloader.cs","lineNumber":40,"sourceCode":"    IEnvironment environment,\n    ILogger<CliDownloader> logger,\n    IInteractionService interactionService,\n    IPackagingService packagingService) : ICliDownloader\n{\n    private const int ArchiveDownloadTimeoutSeconds = 600;\n    private const int ChecksumDownloadTimeoutSeconds = 120;\n\n    private static readonly HttpClient s_httpClient = new();\n\n    public async Task<string> DownloadLatestCliAsync(string channelName, CancellationToken cancellationToken)\n    {\n        // Get the channel information from PackagingService\n        var channels = await packagingService.GetChannelsAsync(cancellationToken, channelName);\n        var channel = channels.FirstOrDefault(c => c.Name.Equals(channelName, StringComparison.OrdinalIgnoreCase));\n\n        if (channel is null)\n        {\n            throw new ArgumentException($\"Unsupported channel '{channelName}'. Available channels: {string.Join(\", \", channels.Select(c => c.Name))}\");\n        }\n\n        if (string.IsNullOrEmpty(channel.CliDownloadBaseUrl))\n        {\n            throw new InvalidOperationException($\"Channel '{channelName}' does not support CLI downloads.\");\n        }\n\n        var baseUrl = channel.CliDownloadBaseUrl.TrimEnd('/');\n\n        var (os, arch) = DetectPlatform();\n        var runtimeIdentifier = $\"{os}-{arch}\";\n        var extension = os == \"win\" ? \"zip\" : \"tar.gz\";\n        var archiveFilename = $\"aspire-cli-{runtimeIdentifier}.{extension}\";\n        var checksumFilename = $\"{archiveFilename}.sha512\";\n        var archiveUrl = $\"{baseUrl}/{archiveFilename}\";\n        var checksumUrl = $\"{baseUrl}/{checksumFilename}\";\n\n        // Create temp directory for download","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Cli/Utils/CliDownloader.cs#L22-L58","documentation":"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.","triggerScenarios":"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.","commonSituations":"Typo in the channel name; using an old channel name removed from packaging metadata; scripting with a hardcoded channel that no longer exists.","solutions":["Use one of the channel names listed in the error message.","Check the spelling/casing conventions of the intended channel.","Enumerate channels via the PackagingService before downloading to validate the name.","Update scripts to the current channel naming after CLI version changes."],"exampleFix":"// before\nawait cliDownloader.DownloadLatestCliAsync(\"stabel\", ct);   // typo\n// after\nawait cliDownloader.DownloadLatestCliAsync(\"stable\", ct);","handlingStrategy":"validation","validationCode":"var channels = await packagingService.GetChannelsAsync(ct);\nif (!channels.Any(c => c.Name.Equals(channelName, StringComparison.OrdinalIgnoreCase)))\n{\n    throw new ArgumentException($\"Unknown channel '{channelName}'. Available: {string.Join(\", \", channels.Select(c => c.Name))}\");\n}","typeGuard":null,"tryCatchPattern":"try { await cliDownloader.DownloadLatestCliAsync(channel, ct); }\ncatch (ArgumentException ex) when (ex.Message.StartsWith(\"Unsupported channel\")) { // list channels and prompt user\n}","preventionTips":["Validate channel names against GetChannelsAsync before downloading.","Avoid hardcoding channel names in scripts; read them from config.","Check spelling against the channel list in the error message."],"tags":["cli","channel","invalid-argument","download"],"backgroundTag":"invalid-enum-value","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}