omnisharp-roslyn icon indicating copy to clipboard operation
omnisharp-roslyn copied to clipboard

With "enableAnalyzersSupport': true, `System.InvalidOperationException: Unable to load Microsoft.Extensions.Logging.Generators`

Open sin-ack opened this issue 11 months ago • 6 comments

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)

sin-ack avatar Jan 13 '25 10:01 sin-ack

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?

sin-ack avatar Jan 13 '25 10:01 sin-ack

Relates to https://github.com/OmniSharp/omnisharp-roslyn/issues/2650 as well

mkorsukov avatar Apr 16 '25 15:04 mkorsukov

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.

sin-ack avatar Apr 16 '25 20:04 sin-ack

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:

  1. 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?
  2. Why is Omnisharp using the same app domain for analyzers at all?
  3. Why can I not disable Razor analyzers?
  4. 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.

UliPlabst avatar Apr 17 '25 08:04 UliPlabst

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.

sin-ack avatar Apr 17 '25 08:04 sin-ack

@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.

xyx-is avatar Oct 07 '25 13:10 xyx-is