Skip to content

Unhandled exception when -pp:File.xml property combined with -v:diag #12248

@agaace

Description

@agaace

Issue Description

MSBuild fails with an unhandled exception when invoked with both -pp:File.xml and -v:diag properties.

The invocation:

msbuild -t:"Restore;Build" -v:diag -pp:"File.xml"

The exception is:

System.InvalidCastException: Unable to cast object of type 'Microsoft.Build.Evaluation.ProjectItem' to type 'Microsoft.Build.Framework.ITaskItem'

Note: the build works fine when -v is set to a different value than diagnostic, for example -v:m, or when no output file is specified for -pp, or when invoking msbuild via dotnet build (but ignores the -v parameter).

Version used in this repro:

MSBuild version 17.14.14+a129329f1 for .NET Framework
17.14.14.31908

Steps to Reproduce

In Visual Studio 2022 Developer Powershell:

Manual steps

  1. Create project folder Hello and navigate inside it.
mkdir Hello
cd ./Hello
  1. Create a new C# console app project inside the folder.
dotnet new console

This will create Hello.csproj project.

  1. Build the project from commandline using these parameteres:
msbuild -t:"Restore;Build" -v:diag -pp:"Preprocessed.xml"

Repro script (save as Repro.ps1)

Repro.ps1.txt

#-----------------------------------------------------------------------------------------------------------------------
# Create project (steps 1-2).
#-----------------------------------------------------------------------------------------------------------------------
$projectName = "Hello"

if (-not (Test-Path "./$projectName/$projectName.csproj"))
{
  Write-Host "Creating project ``$projectName``."
  New-Item -path "./$projectName" -itemType Directory -force | Out-Null
  Push-Location "./$projectName"
  dotnet new console --no-restore
}
else
{
  Push-Location "./$projectName"
}

#-----------------------------------------------------------------------------------------------------------------------
# Clean project (allows this script to be re-run multiple times).
#-----------------------------------------------------------------------------------------------------------------------
Write-Host "Cleaning."
$dirsToDelete = @("./Bin", "./Obj")
$filesToDelete = @("./Preprocessed.xml")

foreach ($path in $dirsToDelete)
{
  if (Test-Path $path)
  {
    Remove-Item -recurse -force -path $path
    Write-Host "Deleted folder: $path."
  }
}

foreach ($path in $filesToDelete)
{
  if (Test-Path $path)
  {
    Remove-Item -path $path
    Write-Host "Deleted file: $path."
  }
}

#-----------------------------------------------------------------------------------------------------------------------
# Build project (step 3).
#-----------------------------------------------------------------------------------------------------------------------
Write-Host "Building."

# This fails with an unhandled exception:
msbuild -t:"Restore;Build" -v:diag -pp:"Preprocessed.xml"

# This works:
# msbuild -t:"Restore;Build" -v:m -pp:"Preprocessed.xml"

# This also works:
# msbuild -t:"Restore;Build" -v:diag -pp

# This also works, but ignores the -v parameter:
# dotnet build -t:"Restore;Build" -v:diag -pp:"Preprocessed.xml"

Pop-Location
Write-Host "Done."

Expected Behavior

  1. Build completes successfully and produces Preprocessed.xml file.

Actual Behavior

  1. Build fails with an unhandled exception but still produces Preprocessed.xml file.

The exception:

Initial Items:

Unhandled Exception: Microsoft.Build.Exceptions.InternalLoggerException: 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.InvalidOperationException: Failed to compare two elements in the array. ---> System.InvalidCastException: Unable to cast object of type 'Microsoft.Build.Evaluation.ProjectItem' to type 'Microsoft.Build.Framework.ITaskItem'.
   at Microsoft.Build.BackEnd.Logging.BaseConsoleLogger.ITaskItemItemSpecComparer.Compare(Object a, Object b)
   at System.Array.SorterObjectArray.InsertionSort(Int32 lo, Int32 hi)
   at System.Array.SorterObjectArray.IntrospectiveSort(Int32 left, Int32 length)
   --- End of inner exception stack trace ---
   at System.Array.SorterObjectArray.IntrospectiveSort(Int32 left, Int32 length)
   at System.Array.Sort(Array keys, Array items, Int32 index, Int32 length, IComparer comparer)
   at System.Collections.ArrayList.Sort(Int32 index, Int32 count, IComparer comparer)
   at Microsoft.Build.BackEnd.Logging.BaseConsoleLogger.WriteItems(SortedList itemTypes)
   at Microsoft.Build.BackEnd.Logging.ParallelConsoleLogger.WriteItems(BuildEventArgs e, IEnumerable items)
   at Microsoft.Build.BackEnd.Logging.ParallelConsoleLogger.StatusEventHandler(Object sender, BuildStatusEventArgs e)
   at Microsoft.Build.BackEnd.Logging.EventSourceSink.RaiseEvent[TArgs](TArgs buildEvent, ArgsHandler`1 handler, ArgsHandler`1 followUpHandler)
   --- End of inner exception stack trace ---
   at Microsoft.Build.Exceptions.InternalLoggerException.Throw(Exception innerException, BuildEventArgs e, String messageResourceName, Boolean initializationException, String[] messageArgs)
   at Microsoft.Build.BackEnd.Logging.EventSourceSink.RaiseEvent[TArgs](TArgs buildEvent, ArgsHandler`1 handler, ArgsHandler`1 followUpHandler)
   at Microsoft.Build.BackEnd.Logging.EventSourceSink.RaiseAnyEvent(BuildEventArgs buildEvent)
   --- End of inner exception stack trace ---
   at Microsoft.Build.Exceptions.InternalLoggerException.Throw(Exception innerException, BuildEventArgs e, String messageResourceName, Boolean initializationException, String[] messageArgs)
   at Microsoft.Build.BackEnd.Logging.EventSourceSink.RaiseAnyEvent(BuildEventArgs buildEvent)
   at Microsoft.Build.BackEnd.Logging.EventSourceSink.RaiseEvent[TArgs](TArgs buildEvent, ArgsHandler`1 handler, ArgsHandler`1 followUpHandler)
   at Microsoft.Build.BackEnd.Logging.LoggingService.RouteBuildEvent(BuildEventArgs eventArg)
   at Microsoft.Build.BackEnd.Logging.LoggingService.RouteBuildEvent(Object loggingEvent)
   at Microsoft.Build.BackEnd.Logging.LoggingService.LoggingEventProcessor(Object loggingEvent)
   at Microsoft.Build.BackEnd.Logging.LoggingService.<StartLoggingEventProcessing>g__LoggingEventProc|151_0()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

Full console output from the build: ConsoleOutput.txt

Note that this works:

msbuild -t:"Restore;Build" -v:m -pp:"Preprocessed.xml"

This also works:

msbuild -t:"Restore;Build" -v:diag -pp

This also works, but ignores the -v parameter:

dotnet build -t:"Restore;Build" -v:diag -pp:"Preprocessed.xml"

Analysis

No response

Versions & Configurations

msbuild --version
MSBuild version 17.14.14+a129329f1 for .NET Framework
17.14.14.31908

dotnet --version
9.0.302

devenv --version
Microsoft Visual Studio 2022 Version 17.14.9 (July 2025)

pwsh --version
PowerShell 7.5.2

Relevant variables

NUMBER_OF_PROCESSORS=16
OS=Windows_NT
POWERSHELL_DISTRIBUTION_CHANNEL=MSI:Windows 10 Pro
PROCESSOR_ARCHITECTURE=AMD64
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 141 Stepping 1, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=8d01

System info

OS Name: Microsoft Windows 11 Pro
Version: 10.0.26100 Build 26100
System Type: x64-based PC

About

Edition: Windows 11 Pro
Version: 24H2
OS Build: 26100.4652
64-bit operating system, x64-based processor

Metadata

Metadata

Assignees

Labels

Area: TasksIssues impacting the tasks shipped in Microsoft.Build.Tasks.Core.dll.triaged

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions