{"record":{"id":"a8795a2ac35c6c8f","repo":"microsoft/aspire","slug":"no-channel-found-matching-query-requestedchannel-valid","errorCode":null,"errorMessage":"No channel found matching '{query.RequestedChannel}'. Valid options are: {string.Join(\", \", allChannels.Select(c => c.Name))}","messagePattern":"No channel found matching '(.+?)'\\. Valid options are: (.+?)","errorType":"exception","errorClass":"ChannelNotFoundException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Cli/Templating/TemplateNuGetConfigService.cs","lineNumber":274,"sourceCode":"        // falls back to nuget.org instead of the local packages. See docs/specs/cli-identity-sidecar.md.\n        var hasLocalPackagesOverride = executionContext.IdentityPackagesDirectory is not null;\n        var hasPrHives = hasLocalPackagesOverride ||\n            (query.IncludePrHives &&\n                (executionContext.GetHiveCount() > 0 ||\n                    allChannels.Any(static c => c.Type is PackageChannelType.Explicit && HasInstalledLocalBuildPackageSource(c))));\n\n        IEnumerable<PackageChannel> channels;\n        if (isUnqualifiedLocalResolution)\n        {\n            channels = allChannels.Where(c =>\n                c.IsBackedByLocalPackageDirectory &&\n                string.Equals(c.Name, executionContext.IdentityChannel, StringComparison.OrdinalIgnoreCase));\n        }\n        else if (!string.IsNullOrEmpty(query.RequestedChannel))\n        {\n            var matchingChannel = allChannels.FirstOrDefault(c =>\n                    string.Equals(c.Name, query.RequestedChannel, StringComparison.OrdinalIgnoreCase))\n                ?? throw new ChannelNotFoundException(\n                    $\"No channel found matching '{query.RequestedChannel}'. Valid options are: \" +\n                    $\"{string.Join(\", \", allChannels.Select(c => c.Name))}\");\n            channels = [matchingChannel];\n        }\n        else if (!string.IsNullOrWhiteSpace(query.SourceOverride))\n        {\n            // Every channel would query the same explicit source, so querying PR/local channels as\n            // well would attach identical results to whichever channel finishes first. Keep the\n            // implicit channel as the deterministic owner unless the user requested a channel.\n            channels = allChannels.Where(c => c.Type is PackageChannelType.Implicit);\n        }\n        else\n        {\n            // If there are hives (PR build directories), include all channels.\n            // Otherwise, only use the implicit/default channel to avoid prompting.\n            channels = hasPrHives\n                ? allChannels\n                : allChannels.Where(c => c.Type is PackageChannelType.Implicit);","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Cli/Templating/TemplateNuGetConfigService.cs#L256-L292","documentation":"TemplateNuGetConfigService.ResolveTemplatePackageAsync throws ChannelNotFoundException when the caller requests a template channel by name that does not exist in the known channel list. The message lists all valid channel names so the caller can pick one.","triggerScenarios":"ResolveTemplatePackageAsync receives a query with a non-empty RequestedChannel that matches no channel name case-insensitively (e.g. `--channel stablex` or a typo like `9.0` when channels are named differently).","commonSituations":"Typo in `aspire` CLI channel flag; channel renamed between releases; scripts hardcoding an old channel name; using a version number where a named channel is expected.","solutions":["Re-run with a valid channel name from the message's list (e.g. `stable`, `daily`, or the exact name shown).","Omit the channel flag to use the default/identity channel resolution.","Update hardcoded scripts/CI to the renamed channel value."],"exampleFix":"// before\naspire new --channel weekly\n// after\naspire new --channel stable","handlingStrategy":"validation","validationCode":"// List valid channels first and validate input:\n// aspire new --channel <name>  — only pass names from: aspire config list / docs\nvar valid = new HashSet<string>(allChannels.Select(c => c.Name), StringComparer.OrdinalIgnoreCase);\nif (!string.IsNullOrEmpty(requestedChannel) && !valid.Contains(requestedChannel))\n    throw new ArgumentException($\"Unknown channel '{requestedChannel}'. Valid: {string.Join(\", \", valid)}\");","typeGuard":null,"tryCatchPattern":"try { await service.ResolveTemplatePackageAsync(query, ct); }\ncatch (ChannelNotFoundException ex)\n{\n    // show ex.Message — it enumerates valid channel names\n}","preventionTips":["Copy channel names from the CLI help/docs, never type from memory","Keep scripts using channel names updated after releases rename them","Prefer omitting the channel flag to use defaults"],"tags":["cli","channels","nuget","templates"],"backgroundTag":"record-not-found","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"}