{"record":{"id":"7f96105e072aab7e","repo":"microsoft/aspire","slug":"failed-to-retrieve-template-packages-via-cache","errorCode":null,"errorMessage":"Failed to retrieve template packages via cache.","messagePattern":"Failed to retrieve template packages via cache\\.","errorType":"exception","errorClass":"NuGetPackageCacheException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Cli/NuGet/NuGetPackageCache.cs","lineNumber":84,"sourceCode":"            packageId.Equals(\"Aspire.Hosting.Integration.Analyzers\", StringComparison.OrdinalIgnoreCase);\n    }\n}\n\ninternal sealed class NuGetPackageCache(IDotNetCliRunner cliRunner, IMemoryCache memoryCache, AspireCliTelemetry telemetry, IFeatures features) : INuGetPackageCache\n{\n    private const int SearchPageSize = 1000;\n\n    public async Task<IEnumerable<NuGetPackage>> GetTemplatePackagesAsync(DirectoryInfo workingDirectory, bool prerelease, FileInfo? nugetConfigFile, CancellationToken cancellationToken)\n    {\n        var nuGetConfigHashSuffix = nugetConfigFile is not null ? await ComputeNuGetConfigHashSuffixAsync(nugetConfigFile, cancellationToken) : string.Empty;\n        var key = $\"TemplatePackages-{workingDirectory.FullName}-{prerelease}-{nuGetConfigHashSuffix}\";\n\n        var packages = await memoryCache.GetOrCreateAsync(key, async (entry) =>\n        {\n            var packages = await GetPackagesAsync(workingDirectory, \"Aspire.ProjectTemplates\", null, prerelease, nugetConfigFile, true, cancellationToken);\n            return packages.Where(p => p.Id.Equals(\"Aspire.ProjectTemplates\", StringComparison.OrdinalIgnoreCase));\n\n        }) ?? throw new NuGetPackageCacheException(ErrorStrings.FailedToRetrieveCachedTemplatePackages);\n\n        return packages;\n    }\n\n    public async Task<IEnumerable<NuGetPackage>> GetIntegrationPackagesAsync(DirectoryInfo workingDirectory, bool prerelease, FileInfo? nugetConfigFile, CancellationToken cancellationToken)\n    {\n        return await GetPackagesAsync(workingDirectory, \"Aspire.Hosting\", null, prerelease, nugetConfigFile, true, cancellationToken);\n    }\n\n    public async Task<IEnumerable<NuGetPackage>> GetCliPackagesAsync(DirectoryInfo workingDirectory, bool prerelease, FileInfo? nugetConfigFile, CancellationToken cancellationToken)\n    {\n        var nuGetConfigHashSuffix = nugetConfigFile is not null ? await ComputeNuGetConfigHashSuffixAsync(nugetConfigFile, cancellationToken) : string.Empty;\n        var key = $\"CliPackages-{workingDirectory.FullName}-{prerelease}-{nuGetConfigHashSuffix}\";\n\n        var packages = await memoryCache.GetOrCreateAsync(key, async (entry) =>\n        {\n            // Set cache expiration to 1 hour for CLI updates\n            entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1);","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Cli/NuGet/NuGetPackageCache.cs#L66-L102","documentation":"NuGetPackageCache.GetTemplatePackagesAsync queries the Aspire.ProjectTemplates package via dotnet search and caches it in IMemoryCache. MemoryCache.GetOrCreateAsync can return null when the cached factory produces null; the code treats a null result as a cache failure and throws NuGetPackageCacheException 'Failed to retrieve template packages via cache.'","triggerScenarios":"GetTemplatePackagesAsync (e.g. `aspire new` template listing) when GetOrCreateAsync returns null — effectively when the underlying GetPackagesAsync search produced a null/empty result for Aspire.ProjectTemplates that collapsed to null in the cache path.","commonSituations":"NuGet source unreachable or misconfigured so the ProjectTemplates package is not found; template package filtered out by the Id filter; transient NuGet failure during `aspire new`; restrictive nuget.config in the working directory hiding nuget.org.","solutions":["Check network access to nuget.org (or your configured feed) and ensure Aspire.ProjectTemplates is available there","Inspect/fix nuget.config in the working directory or pass an explicit --nuget-config","Retry the command (the result is cached; a transient search failure may clear on retry)","Update the Aspire CLI; if it persists, run with debug logging and report the underlying search failure"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Confirm the template package is visible on the configured source first\ndotnet package search Aspire.ProjectTemplates --exact-match --prerelease","typeGuard":null,"tryCatchPattern":"try\n{\n    var templates = await cache.GetTemplatePackagesAsync(workingDir, prerelease, nugetConfig, ct);\n}\ncatch (NuGetPackageCacheException ex) when (ex.Message.Contains(\"Failed to retrieve template packages\"))\n{\n    // check feed connectivity / nuget.config, then retry\n}","preventionTips":["Ensure nuget.org (or your mirror carrying Aspire.ProjectTemplates) is reachable and configured","Avoid restrictive nuget.config files in directories where `aspire new` runs","Retry transient failures; results are memory-cached so subsequent calls are cheap","Keep the CLI updated so its search pipeline matches current feed behavior"],"tags":["nuget","templates","cache","search"],"backgroundTag":"empty-result-set","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"}