Skip to content

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

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

Fields

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions