dotnet / installer

.NET SDK Installer
https://github.com/dotnet/sdk
1.27k stars 446 forks source link

[6.0.100-preview.5] dotnet new throws "An item with the same key has already been added" on macOS #10917

Closed mdmsua closed 3 years ago

mdmsua commented 3 years ago

After upgrading from preview.4, 6.0.100-preview.5.21302.13 throws "An item with the same key has already been added" exception on every invocation of "dotnet new" command:

➜  dotnet new
An item with the same key has already been added. Key: microsoft-tvos-sdk-full
   at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior) in System.Private.CoreLib.dll:token 0x60062bb+0x1a0
   at Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver.RefreshWorkloadManifests() in Microsoft.DotNet.TemplateLocator.dll:token 0x6000065+0x1b2
   at Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver..ctor(IWorkloadManifestProvider manifestProvider, String[] dotnetRootPaths, String[] currentRuntimeIdentifiers) in Microsoft.DotNet.TemplateLocator.dll:token 0x6000064+0x31
   at Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver.Create(IWorkloadManifestProvider manifestProvider, String dotnetRootPath, String sdkVersion) in Microsoft.DotNet.TemplateLocator.dll:token 0x6000062+0x8a
   at Microsoft.DotNet.TemplateLocator.TemplateLocator.GetDotnetSdkTemplatePackages(String sdkVersion, String dotnetRootPath) in Microsoft.DotNet.TemplateLocator.dll:token 0x600008f+0x4d
   at Microsoft.DotNet.Tools.New.OptionalWorkloadProvider.GetAllTemplatePackagesAsync(CancellationToken cancellationToken) in dotnet.dll:token 0x600030b+0x3a
   at Microsoft.TemplateEngine.Edge.Settings.TemplatePackageManager.<>c__DisplayClass21_0.<EnsureProvidersLoaded>b__2() in Microsoft.TemplateEngine.Edge.dll:token 0x60002c3+0x0
   at System.Threading.Tasks.Task`1.InnerInvoke() in System.Private.CoreLib.dll:token 0x6002ba9+0xf
   at System.Threading.Tasks.Task.<>c.<.cctor>b__284_0(Object obj) in System.Private.CoreLib.dll:token 0x6002d49+0x0
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) in System.Private.CoreLib.dll:token 0x6002919+0x15
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) in System.Private.CoreLib.dll:token 0x6002919+0x46
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread) in System.Private.CoreLib.dll:token 0x6002ca3+0xa5
--- End of stack trace from previous location ---
   at Microsoft.TemplateEngine.Edge.Settings.TemplatePackageManager.GetTemplatePackagesAsync(Boolean force, CancellationToken cancellationToken) in Microsoft.TemplateEngine.Edge.dll:token 0x6000158+0x15a
   at Microsoft.TemplateEngine.Edge.Settings.TemplatePackageManager.UpdateTemplateCacheAsync(Boolean needsRebuild, CancellationToken cancellationToken) in Microsoft.TemplateEngine.Edge.dll:token 0x6000161+0x1c8
   at Microsoft.TemplateEngine.Edge.Settings.TemplatePackageManager.GetTemplatesAsync(CancellationToken cancellationToken) in Microsoft.TemplateEngine.Edge.dll:token 0x600015b+0x7e
   at Microsoft.TemplateEngine.Cli.New3Command.EnterMaintenanceFlowAsync() in Microsoft.TemplateEngine.Cli.dll:token 0x6000142+0xef
   at Microsoft.TemplateEngine.Cli.New3Command.ExecuteAsync() in Microsoft.TemplateEngine.Cli.dll:token 0x6000144+0x497
   at Microsoft.TemplateEngine.Cli.CommandParsing.NewCommandInputCli.<>c__DisplayClass100_0.<<OnExecute>b__0>d.MoveNext() in Microsoft.TemplateEngine.Cli.dll:token 0x60004c4+0x71

The reason is duplicated workload entries in SDK manifests:

➜  grep -r "microsoft-tvos-sdk-full" /usr/local/share/dotnet
/usr/local/share/dotnet/sdk-manifests/6.0.100/microsoft.net.sdk.tvos/WorkloadManifest.json:     "microsoft-tvos-sdk-full": {
/usr/local/share/dotnet/sdk-manifests/6.0.100/Microsoft.NET.Workload.tvOS/WorkloadManifest.json:        "microsoft-tvos-sdk-full": {

I suppose Microsoft.NET.Workload. folders are leftovers after preview 4, cause the directory modification timestamp corresponds to the point when I've installed preview 4:

➜   la /usr/local/share/dotnet/sdk-manifests/6.0.100/
total 0
drwxr-xr-x  4 root  wheel   128B  5 Mai 21:34 Microsoft.NET.Workload.Android
drwxr-xr-x  4 root  wheel   128B  5 Mai 21:34 Microsoft.NET.Workload.BlazorWebAssembly
drwxr-xr-x  4 root  wheel   128B  5 Mai 21:34 Microsoft.NET.Workload.MacCatalyst
drwxr-xr-x  4 root  wheel   128B  5 Mai 21:34 Microsoft.NET.Workload.iOS
drwxr-xr-x  4 root  wheel   128B  5 Mai 21:34 Microsoft.NET.Workload.macOS
drwxr-xr-x  4 root  wheel   128B  5 Mai 21:34 Microsoft.NET.Workload.tvOS
drwxr-xr-x  4 root  wheel   128B 18 Jun 12:48 microsoft.net.sdk.android
drwxr-xr-x  4 root  wheel   128B 18 Jun 12:48 microsoft.net.sdk.ios
drwxr-xr-x  4 root  wheel   128B 18 Jun 12:48 microsoft.net.sdk.maccatalyst
drwxr-xr-x  4 root  wheel   128B 18 Jun 12:48 microsoft.net.sdk.macos
drwxr-xr-x  4 root  wheel   128B 18 Jun 12:48 microsoft.net.sdk.tvos
drwxr-xr-x  4 root  wheel   128B 18 Jun 12:48 microsoft.net.workload.mono.toolchain

Is it safe to simply those?

delneg commented 3 years ago

Having the same issue on x64 mac using 6.0.100-preview.5.21302.13

delneg@tests-MacBook-Pro /tmp [1]> dotnet workload update
System.ArgumentException: An item with the same key has already been added. Key: microsoft-tvos-sdk-full
   at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior) in System.Private.CoreLib.dll:token 0x60062cb+0x1a0
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value) in System.Private.CoreLib.dll:token 0x60062be+0x0
   at Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver.RefreshWorkloadManifests() in Microsoft.DotNet.TemplateLocator.dll:token 0x6000065+0x1b2
   at Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver..ctor(IWorkloadManifestProvider manifestProvider, String[] dotnetRootPaths, String[] currentRuntimeIdentifiers) in Microsoft.DotNet.TemplateLocator.dll:token 0x6000064+0x31
   at Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver.Create(IWorkloadManifestProvider manifestProvider, String dotnetRootPath, String sdkVersion) in Microsoft.DotNet.TemplateLocator.dll:token 0x6000062+0x8a
   at Microsoft.DotNet.Workloads.Workload.Update.WorkloadUpdateCommand..ctor(ParseResult parseResult, IReporter reporter, IWorkloadResolver workloadResolver, IInstaller workloadInstaller, INuGetPackageDownloader nugetPackageDownloader, IWorkloadManifestUpdater workloadManifestUpdater, String dotnetDir, String userHome, String version) in dotnet.dll:token 0x6000153+0xb8
   at Microsoft.DotNet.Workloads.Workload.WorkloadCommand.<get_SubCommands>b__9_2(ParseResult appliedOption) in dotnet.dll:token 0x600014a+0x0
   at Microsoft.DotNet.Cli.DotNetTopLevelCommandBase.RunCommand(String[] args) in dotnet.dll:token 0x60008ca+0x44
   at Microsoft.DotNet.Workloads.Workload.WorkloadCommand.Run(String[] args) in dotnet.dll:token 0x6000146+0x6
   at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, TimeSpan startupTime, ITelemetry telemetryClient) in dotnet.dll:token 0x6000933+0x2e8
   at Microsoft.DotNet.Cli.Program.Main(String[] args) in dotnet.dll:token 0x6000931+0x6f

Edit: the issue was resolved by downloading 6.0.100-preview.6.21319.1 from README of this repo.

mdmsua commented 3 years ago

Manually removing old "Microsoft.NET.Workload.*" also resolves the issue

marcpopMSFT commented 3 years ago

[Workaround] Thanks for reporting this. I’ve created a PR to update the known issues to cover this: https://github.com/dotnet/core/pull/6396

To get Preview 5 working, install Preview 5 again and then apply one of the following workarounds:

In the .NET SDK installation folder, delete all folders under sdk-manifests\6.0.100 (for example, under C:\Program Files\dotnet\sdk-manifests\6.0.100) that have the form Microsoft.NET.Workload.*, EXCEPT for microsoft.net.workload.mono.toolchain

Or

If you want to use .NET Maui, you can run the latest version of the maui-check tool. This will delete the outdated manifest folders and set up your environment for .NET Maui development.