Skip to content

VBCSCompilerLogger: MissingMethodException on CommandLineArguments.Errors - not wrapped in tryAccessCommandLineArgument #1354

@HelcioMEng

Description

@HelcioMEng

I had help of AI generated information regarding this issue and I hope information below is useful.

Summary
VBCSCompilerLogger crashes with MissingMethodException when used with MSBuild installations that ship a different version of Microsoft.CodeAnalysis than what the logger was compiled against. The CommandLineArguments.Errors property access is not wrapped in the tryAccessCommandLineArgument helper, unlike other version-sensitive property accesses in the same file.

Environment
BuildXL: 0.1.0-devBuild (built from source, C:\tools\BuildXL-src\Out\Bin\Debug\win-x64\bxl.exe)
MSBuild: 17.x (Visual Studio 2022 BuildTools / Professional)
MsBuild resolver with msBuildRuntime: "FullFramework", useManagedSharedCompilation: true
Windows build nodes
Error (Option A — standard VBCSCompilerLogger.dll from Out\Bin\Debug\win-x64\tools\vbcslogger\net472)

MSBUILD : error MSB4017: The build stopped unexpectedly because of an unexpected logger failure.
Microsoft.Build.Exceptions.InternalLoggerException: The build stopped unexpectedly because of an unexpected logger failure.
---> System.MissingMethodException: Method not found:
'System.Collections.Immutable.ImmutableArray`1<Microsoft.CodeAnalysis.Diagnostic>
Microsoft.CodeAnalysis.CommandLineArguments.get_Errors()'.
at VBCSCompilerLogger.VBCSCompilerLogger.EventSourceOnMessageRaised(Object sender, BuildMessageEventArgs e)

Error (Option B — VBCSCompilerLoggerOldCodeAnalysis.dll from Out\Objects...\testRun\Logger, renamed to VBCSCompilerLogger.dll)

MSBUILD : error MSB1028: The logger failed unexpectedly.
System.IO.FileNotFoundException: Could not load file or assembly
'Microsoft.CodeAnalysis, Version=2.10.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
or one of its dependencies. The system cannot find the file specified.
at VBCSCompilerLogger.VBCSCompilerLogger..ctor()

Root Cause
In VBCSCompilerLogger.cs, the EventSourceOnMessageRaised method accesses parsedCommandLine.Errors directly:
IEnumerable badSwitchErrors = parsedCommandLine.Errors
.Where(diagnostic => diagnostic.Id.Contains("2007")).ToList();

This property was added in a newer version of Microsoft.CodeAnalysis. Unlike other version-sensitive accesses in the same method (e.g., AnalyzerReferences, EmbeddedFiles, AdditionalFiles, AnalyzerConfigPaths, ErrorLogOptions, etc.), the .Errors property is not wrapped in the tryAccessCommandLineArgument helper that gracefully handles MissingMethodException:

static T? tryAccessCommandLineArgument(Func accessCommandLineArgument)
{
try { return accessCommandLineArgument(); }
catch (MissingMethodException) { return default; }
}

Proposed Fix
Wrap the parsedCommandLine.Errors access in tryAccessCommandLineArgument:

ImmutableArray errors = tryAccessCommandLineArgument(() => parsedCommandLine.Errors);
IEnumerable badSwitchErrors = errors != default
? errors.Where(diagnostic => diagnostic.Id.Contains("2007")).ToList()
: Enumerable.Empty();

his is consistent with how all other version-sensitive CommandLineArguments properties are accessed in the same method.

Workaround
Set useManagedSharedCompilation: false in the resolver configuration. This disables the VBCSCompilerLogger entirely but results in slightly slower C# builds (no shared Roslyn compiler service).

Thanks a lot

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions