With "enableAnalyzersSupport': true, `System.InvalidOperationException: Unable to load Microsoft.Extensions.Logging.Generators`
System information
OS: Gentoo Linux 2.17 amd64 (x86_64-pc-linux-gnu) .NET versions:
- 8.0.107 (active)
- 9.0.101
OmniSharp version: 1.39 Editor: Emacs 30.0.92 Language Server Client: lsp-mode Project Package Manager: Paket 9.0.2 Project .NET Version: .NET 8.0
Expected behavior
Hovering over analyzer-generated diagnostics and attempting to apply code fixes should work without errors.
Actual behavior
I decided to try out "RosylnExtensionsOptions": {"enableAnalyzersSupport": true}. It works fine most of the time, however when I hover over an IDE warning generated by such an analyzer, I get the following in my messages area. Example diagnostic with this error: IDE0290.
Error message
Error from the Language Server: Internal Error - System.InvalidOperationException: Unable to load Microsoft.Extensions.Logging.Generators
---> System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Extensions.Logging.Generators, Version=8.0.10.46610, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.
File name: 'Microsoft.Extensions.Logging.Generators, Version=8.0.10.46610, Culture=neutral, PublicKeyToken=adb9793829ddae60'
at System.Reflection.RuntimeAssembly.<InternalLoad>g____PInvoke|49_0(NativeAssemblyNameParts* __pAssemblyNameParts_native, ObjectHandleOnStack __requestingAssembly_native, StackCrawlMarkHandle __stackMark_native, Int32 __throwOnFileNotFound_native, ObjectHandleOnStack __assemblyLoadContext_native, ObjectHandleOnStack __retAssembly_native)
at System.Reflection.RuntimeAssembly.InternalLoad(AssemblyName assemblyName, StackCrawlMark& stackMark, AssemblyLoadContext assemblyLoadContext, RuntimeAssembly requestingAssembly, Boolean throwOnFileNotFound)
at System.Reflection.Assembly.Load(AssemblyName assemblyRef)
at System.AppDomain.Load(AssemblyName assemblyRef)
at Microsoft.CodeAnalysis.AnalyzerAssemblyLoader.Load(AssemblyName assemblyName, String assemblyOriginalPath)
at Microsoft.CodeAnalysis.AnalyzerAssemblyLoader.LoadFromPath(String originalAnalyzerPath)
--- End of inner exception stack trace ---
at Microsoft.CodeAnalysis.AnalyzerAssemblyLoader.LoadFromPath(String originalAnalyzerPath)
at Microsoft.CodeAnalysis.Diagnostics.AnalyzerFileReference.GetAssembly()
at OmniSharp.Roslyn.CSharp.Services.Refactoring.V2.CachingCodeFixProviderForProjects.<>c__DisplayClass6_0.<LoadFrom>b__0(AnalyzerFileReference analyzerFileReference) in /home/vsts/work/1/s/src/OmniSharp.Roslyn.CSharp/Services/Refactoring/V2/CachingCodeFixProviderForProjects.cs:line 64
at System.Linq.Enumerable.SelectManySingleSelectorIterator`2.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
at System.Collections.Generic.SparseArrayBuilder`1.ReserveOrAdd(IEnumerable`1 items)
at System.Linq.Enumerable.Concat2Iterator`1.ToArray()
at System.Collections.Immutable.ImmutableArray.CreateRange[T](IEnumerable`1 items)
at OmniSharp.Roslyn.CSharp.Services.Refactoring.V2.CachingCodeFixProviderForProjects.LoadFrom(Project project) in /home/vsts/work/1/s/src/OmniSharp.Roslyn.CSharp/Services/Refactoring/V2/CachingCodeFixProviderForProjects.cs:line 95
at OmniSharp.Roslyn.CSharp.Services.Refactoring.V2.CachingCodeFixProviderForProjects.GetAllCodeFixesForProject(ProjectId projectId) in /home/vsts/work/1/s/src/OmniSharp.Roslyn.CSharp/Services/Refactoring/V2/CachingCodeFixProviderForProjects.cs:line 57
at OmniSharp.Roslyn.CSharp.Services.Refactoring.V2.BaseCodeActionService`2.GetSortedCodeFixProviders(Document document) in /home/vsts/work/1/s/src/OmniSharp.Roslyn.CSharp/Services/Refactoring/V2/BaseCodeActionService.cs:line 166
at OmniSharp.Roslyn.CSharp.Services.Refactoring.V2.BaseCodeActionService`2.AppendFixesAsync(Document document, TextSpan span, IEnumerable`1 diagnostics, List`1 codeActions) in /home/vsts/work/1/s/src/OmniSharp.Roslyn.CSharp/Services/Refactoring/V2/BaseCodeActionService.cs:line 139
at OmniSharp.Roslyn.CSharp.Services.Refactoring.V2.BaseCodeActionService`2.CollectCodeFixesActions(Document document, TextSpan span, List`1 codeActions) in /home/vsts/work/1/s/src/OmniSharp.Roslyn.CSharp/Services/Refactoring/V2/BaseCodeActionService.cs:line 133
at OmniSharp.Roslyn.CSharp.Services.Refactoring.V2.BaseCodeActionService`2.GetAvailableCodeActions(ICodeActionRequest request) in /home/vsts/work/1/s/src/OmniSharp.Roslyn.CSharp/Services/Refactoring/V2/BaseCodeActionService.cs:line 85
at OmniSharp.Roslyn.CSharp.Services.Refactoring.V2.GetCodeActionsService.Handle(GetCodeActionsRequest request) in /home/vsts/work/1/s/src/OmniSharp.Roslyn.CSharp/Services/Refactoring/V2/GetCodeActionsService.cs:line 34
at OmniSharp.LanguageServerProtocol.Handlers.OmniSharpCodeActionHandler.Handle(CodeActionParams request, CancellationToken cancellationToken) in /home/vsts/work/1/s/src/OmniSharp.LanguageServerProtocol/Handlers/OmniSharpCodeActionHandler.cs:line 70
at OmniSharp.Extensions.LanguageServer.Server.Pipelines.SemanticTokensDeltaPipeline`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
at OmniSharp.Extensions.LanguageServer.Server.Pipelines.ResolveCommandPipeline`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
at MediatR.Pipeline.RequestPreProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
at MediatR.Pipeline.RequestPostProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
at MediatR.Pipeline.RequestExceptionProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
at MediatR.Pipeline.RequestExceptionProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
at MediatR.Pipeline.RequestExceptionActionProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
at MediatR.Pipeline.RequestExceptionActionProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)
at OmniSharp.Extensions.JsonRpc.RequestRouterBase`1.<RouteRequest>g__InnerRoute|7_0(IServiceScopeFactory serviceScopeFactory, Request request, TDescriptor descriptor, Object params, CancellationToken token, ILogger logger)
at OmniSharp.Extensions.JsonRpc.RequestRouterBase`1.RouteRequest(IRequestDescriptor`1 descriptors, Request request, CancellationToken token)
at OmniSharp.Extensions.JsonRpc.DefaultRequestInvoker.<>c__DisplayClass10_0.<<RouteRequest>b__5>d.MoveNext() (Internal Error)
I tried to build OmniSharp to see whether I could figure out what path it was trying to load that was causing this error but I'm having a lot of trouble getting Cake to cooperate. Is there a way to avoid publishing every single version and just run the latest .NET version for debugging?
Relates to https://github.com/OmniSharp/omnisharp-roslyn/issues/2650 as well
I think I figured it out. It's because to load analyzers, OmniSharp loads them directly into the current AppDomain instead of using a separate one. If an assembly shipped with OmniSharp is older than what the analyzer needs, the analyzer will fail to load its dependent assembly (because it's already cached in the domain) and report a FileNotFound.
Related #6718 and #2627 . Analyzers and omnisharp have been broken forever. We really need a fix for this. There is a workaround: <RunAnalzyers>false</RunAnalyzers> in csproj but this disables all analyzers which effectively not using any SourceGenerators (or at least not having any Omnisharp LSP support for it).
I get a very similar exception
Unable to load Microsoft.AspNetCore.Razor.Utilities.Shared\\r\\n ---> System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.AspNetCore.Razor.Utilities.Shared, Version=9.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.\\r\\nFile name: 'Microsoft.AspNetCore.Razor.Utilities.Shared, Version=9.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'
which is very frustrating because I'm not even using Razor anywhere.
A couple of questions:
- Why is Omnisharp trying to load the Version 9.0.0.0 of the library when I have set the sdk path to 8.0.403?
- Why is Omnisharp using the same app domain for analyzers at all?
- Why can I not disable Razor analyzers?
- Why do code completions fail completely if one analyzer fails?
Maybe a quick workaround would be to implement a whitelist option for analyzers so that the user can at least disable the ones that cause the exception.
Why is Omnisharp trying to load the Version 9.0.0.0 of the library when I have set the sdk path to 8.0.403?
OmniSharp likely uses your project's NuGet dependency graph, and something might've bumped it to 9.0.0.0. .NET dependencies (Microsoft's in particular) don't actually constrain to the current major version; a 8.x.x.x package in the Microsoft.AspNetCore namespace can easily pul a 9.x.x.x version of another package.
Why is Omnisharp using the same app domain for analyzers at all?
Probably because it's easier to implement. With a separate AppDomain you're essentially running two separate programs, so it becomes more complicated to communicate.
@UliPlabst Regarding your comment:
Why can I not disable Razor analyzers?
This may not help in every case, but there might be a workaround to effectively disable the Razor plugin when using OmniSharp in VS Code (for projects that do not use Razor). I described the steps here: https://github.com/dotnet/vscode-csharp/issues/7926#issuecomment-3376663931
In short, by removing the OmniSharpPlugin directory inside the .razoromnisharp folder (created under the C# extension installation directory), OmniSharp appears to stop loading the Razor plugin.
This is not an official fix and may not work in all environments, but it could serve as a temporary workaround.