{"record":{"id":"84746686515e16c3","repo":"microsoft/aspire","slug":"channel-channelname-does-not-support-cli-downloads","errorCode":null,"errorMessage":"Channel '{channelName}' does not support CLI downloads.","messagePattern":"Channel '(.+?)' does not support CLI downloads\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Cli/Utils/CliDownloader.cs","lineNumber":45,"sourceCode":"    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\n        var tempDir = Directory.CreateTempSubdirectory(\"aspire-cli-download\").FullName;\n\n        try\n        {\n            var archivePath = Path.Combine(tempDir, archiveFilename);","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Cli/Utils/CliDownloader.cs#L27-L63","documentation":"DownloadLatestCliAsync throws InvalidOperationException when the resolved channel exists but its CliDownloadBaseUrl is null or empty, meaning the channel is valid for package resolution but does not host CLI binaries for download.","triggerScenarios":"Requesting a CLI download from a channel whose packaging metadata lacks CliDownloadBaseUrl — typically feed-only or template-only channels.","commonSituations":"Using a channel intended only for NuGet package consumption (not binary distribution); local/packaging channels without download URLs configured.","solutions":["Switch to a channel that supports CLI binary downloads (has CliDownloadBaseUrl).","Obtain the CLI via another distribution path (installer scripts, GitHub releases) instead of this channel.","If this is an internal channel, populate CliDownloadBaseUrl in its packaging metadata."],"exampleFix":"// before\nawait cliDownloader.DownloadLatestCliAsync(\"template-only-channel\", ct);\n// after\nawait cliDownloader.DownloadLatestCliAsync(\"stable\", ct);   // channel with CliDownloadBaseUrl","handlingStrategy":"validation","validationCode":"var channels = await packagingService.GetChannelsAsync(ct);\nvar channel = channels.FirstOrDefault(c => c.Name.Equals(channelName, StringComparison.OrdinalIgnoreCase));\nif (channel is null || string.IsNullOrEmpty(channel.CliDownloadBaseUrl))\n{\n    throw new InvalidOperationException($\"Channel '{channelName}' does not support CLI downloads.\");\n}","typeGuard":null,"tryCatchPattern":"try { await cliDownloader.DownloadLatestCliAsync(channel, ct); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"does not support CLI downloads\")) { // fall back to installer script or another channel\n}","preventionTips":["Check channel.CliDownloadBaseUrl is non-empty before attempting CLI download.","Use channels documented as supporting binary CLI distribution.","Provide a fallback install path (installer scripts) for non-download channels."],"tags":["cli","channel","unsupported-operation","download"],"backgroundTag":"unsupported-operation","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"}