I was not able to reproduce the issue on a synthetic project, but it can be steadily reproduced on 'Orleans' framework sources (Windows 10, MSBuild 14).
The code to reproduce as follows:
MSBuildWorkspace workspace = MSBuildWorkspace.Create(properties);
var project = workspace.OpenProjectAsync(projectPath).Result
The path to '\Orleans\src\ClientGenerator\ClientGenerator.csproj' project should be passed. The exception will occur when Roslyn begins loading one of this project's dependencies (Orleans.csproj to be precise):
Error was encountered while opening project 'ClientGenerator\ClientGenerator.csproj'.
Exception message:
One or more errors occurred.
Stack: at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at ProgramVerificationSystems.PVSStudio.Analyzer.Core.DotNetAnalyzer.ParseProjectInSolution(ProjectInSolution sender, SolutionConfigurationInSolution solutionConfigurationInSolution, String solutionFile) in D:\home\paul\SVN\viva64\PVS-Studio\PVS-Studio\Analyzer\Core\DotNetAnalyzer.cs:line 268
Inner Exception:
Exception message:
An item with the same key has already been added.
Stack: at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at Microsoft.CodeAnalysis.RuleSet.GetDiagnosticOptionsFromRulesetFile(Dictionary`2 diagnosticOptions, String resolvedPath, IList`1 diagnosticsOpt, CommonMessageProvider messageProviderOpt)
at Microsoft.CodeAnalysis.CSharp.CSharpCommandLineParser.Parse(IEnumerable`1 args, String baseDirectory, String sdkDirectory, String additionalReferenceDirectories)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.<LoadProjectAsync>d__23.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.<GetOrLoadProjectAsync>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.<ResolveProjectReferencesAsync>d__28.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.<LoadProjectAsync>d__23.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.<GetOrLoadProjectAsync>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.<ResolveProjectReferencesAsync>d__28.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.<LoadProjectAsync>d__23.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.<LoadProjectInfoAsync>d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.<OpenProjectAsync>d__19.MoveNext()
I've managed to trace the issue down to CSharpCompilerInputs returning a duplicate argument ("/ruleset:\"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Team Tools\\Static Analysis Tools\\\\Rule Sets\\MinimumRecommendedRules.ruleset\"" after building it (CSharpProjectFileLoader.GetProjectFileInfoAsync method). Duplicated ruleset leads to duplicated list of diagnostics, thus leading to the exception (there is no check for key already existing in the dictionary before it is appended).
I was not able to reproduce the issue on a synthetic project, but it can be steadily reproduced on 'Orleans' framework sources (Windows 10, MSBuild 14).
The code to reproduce as follows:
The path to '\Orleans\src\ClientGenerator\ClientGenerator.csproj' project should be passed. The exception will occur when Roslyn begins loading one of this project's dependencies (Orleans.csproj to be precise):
I've managed to trace the issue down to
CSharpCompilerInputs
returning a duplicate argument ("/ruleset:\"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Team Tools\\Static Analysis Tools\\\\Rule Sets\\MinimumRecommendedRules.ruleset\""
after building it (CSharpProjectFileLoader.GetProjectFileInfoAsync
method). Duplicated ruleset leads to duplicated list of diagnostics, thus leading to the exception (there is no check for key already existing in the dictionary before it is appended).