{"record":{"id":"58709e82c0e88489","repo":"microsoft/aspire","slug":"reason-dynamic-staging-channel-unavailable-message-from","errorCode":null,"errorMessage":"{reason} (dynamic staging-channel unavailable message from IPackagingService.GetStagingChannelUnavailableReason)","messagePattern":"(.+?) \\(dynamic staging-channel unavailable message from IPackagingService\\.GetStagingChannelUnavailableReason\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs","lineNumber":1001,"sourceCode":"\n    /// <summary>\n    /// Throws when the caller asked for the staging channel but the running CLI's packaging\n    /// service refuses to synthesize one (daily/local/pr-<c>N</c> identity without\n    /// <c>overrideStagingFeed</c> or the <c>StagingChannelEnabled</c> feature flag). Surfaces\n    /// the same actionable reason the <c>update</c> and <c>new</c> commands display so the\n    /// bundled AppHost restore path doesn't silently downgrade to the daily feed.\n    /// </summary>\n    private void ThrowIfStagingUnavailable(string? requestedChannel)\n    {\n        if (!string.Equals(requestedChannel, PackageChannelNames.Staging, StringComparisons.ChannelName))\n        {\n            return;\n        }\n\n        var reason = _packagingService.GetStagingChannelUnavailableReason();\n        if (reason is not null)\n        {\n            throw new InvalidOperationException(reason);\n        }\n    }\n\n    /// <summary>\n    /// Gets NuGet sources from the resolved channel for bundled restore.\n    /// </summary>\n    internal async Task<IEnumerable<string>?> GetNuGetSourcesAsync(string? requestedChannel, string? packageSourceOverride, CancellationToken cancellationToken)\n    {\n        // Refuse to silently downgrade staging restores to the shared daily feed when the running\n        // CLI cannot synthesize a real staging channel (daily/local/pr-<N>). PackagingService omits\n        // the staging channel in that case; without this check the lookup below falls through to\n        // \"all explicit channels\" — which on a daily CLI is the shared daily feed — and restore\n        // silently succeeds against the wrong feed. Surfacing the actionable\n        // GetStagingChannelUnavailableReason() mirrors UpdateCommand/NewCommand and closes the\n        // bundled-AppHost arm of https://github.com/microsoft/aspire/issues/16652.\n        ThrowIfStagingUnavailable(requestedChannel);\n\n        var sources = new List<string>();","sourceCodeStart":983,"sourceCodeEnd":1019,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs#L983-L1019","documentation":"Before performing a bundled restore from a staging channel, PrebuiltAppHostServer consults IPackagingService.GetStagingChannelUnavailableReason(). If that returns a non-null reason string, the staging channel cannot be used (e.g. not configured, disabled, or unsupported) and the CLI throws InvalidOperationException with that reason as the message. The '{reason} (dynamic staging-channel unavailable message...)' text is the template — the actual thrown message is the reason returned by the service.","triggerScenarios":"Initiating a bundled restore of a prebuilt AppHost while the staging feed is unavailable: ASPIRE_STAGING_CHANNEL / channel configuration points at a channel that is disabled, not yet published, or not enabled for the current build quality.","commonSituations":"Using a daily/staging CLI build against a channel whose feed hasn't been published; setting ASPIRE_CHANNEL or ASPIRE_STAGING_CHANNEL to an invalid or retired channel; corporate proxies blocking the staging feed so the service reports it unavailable.","solutions":["Switch to a stable/GA channel (unset ASPIRE_STAGING_CHANNEL or set ASPIRE_CHANNEL=stable) and retry.","Read the thrown reason message — it comes from GetStagingChannelUnavailableReason and states the exact channel problem — and fix that condition.","Verify network access to the staging NuGet feed; configure proxy/credentials if the feed is blocked.","Use a CLI version whose channel is actually published."],"exampleFix":"// before\nexport ASPIRE_STAGING_CHANNEL=daily\n// after\nunset ASPIRE_STAGING_CHANNEL  # or: export ASPIRE_CHANNEL=stable","handlingStrategy":"fallback","validationCode":"var reason = packagingService.GetStagingChannelUnavailableReason();\nif (reason is not null) { Console.WriteLine($\"Staging channel unavailable: {reason}\"); /* switch to stable */ }","typeGuard":"static bool StagingChannelUsable(IPackagingService svc) => svc.GetStagingChannelUnavailableReason() is null;","tryCatchPattern":"try { await server.RunAsync(ct); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"channel\"))\n{ logger.LogWarning(\"Staging channel unavailable: {Reason} — retrying with stable channel\", ex.Message); await RetryWithStableChannelAsync(ct); }","preventionTips":["Pin ASPIRE_CHANNEL/staging-channel config to a channel you know is published.","Unset staging-channel overrides for production/CI runs.","Check feed connectivity and proxy settings before bundled restores.","Keep the CLI on a released version whose channel exists."],"tags":["cli","nuget","staging-channel","configuration"],"backgroundTag":"invalid-config-value","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"}