Summary
-mt (experimental multithreaded MSBuild) and -reportfileaccesses cannot be used together. Combining them fails the build immediately with an internal error, before any project work happens:
MSBUILD : error MSB1025: An internal failure occurred while running MSBuild.
Microsoft.Build.Framework.InternalErrorException: MSB0001: Internal MSBuild Error: We failed to request a node to be created.
at Microsoft.Build.Shared.ErrorUtilities.ThrowInternalError(String message, Exception innerException, Object[] args)
at Microsoft.Build.Shared.ErrorUtilities.VerifyThrow(Boolean condition, String unformattedMessage)
at Microsoft.Build.BackEnd.Scheduler.ScheduleUnassignedRequests(List`1 responses)
at Microsoft.Build.BackEnd.Scheduler.ReportRequestBlocked(Int32 nodeId, BuildRequestBlocker blocker)
at Microsoft.Build.Execution.BuildManager.HandleNewRequest(Int32 node, BuildRequestBlocker blocker)
This was found while investigating #14824.
Steps to reproduce
Any project at all, using the x64 .NET Framework MSBuild (file-access reporting is only compiled into the net472 build, and it additionally requires x64):
<Project>
<TargetName="Build">
<MessageImportance="High"Text="hello" />
</Target>
</Project>
MSBuild.exe trivial.proj -mt -reportfileaccesses
Actual behavior
MSB1025 / MSB0001: We failed to request a node to be created.
Either switch on its own works fine (-mt alone prints hello; -reportfileaccesses alone builds normally).
Expected behavior
Either the combination works, or MSBuild reports a clear, actionable error explaining that the two switches are mutually exclusive.
Root cause
The two features make contradictory demands on node affinity:
BuildManager.EnableDetouredNodeLauncher (src/Build/BackEnd/BuildManager/BuildManager.cs) sets _buildParameters.DisableInProcNode = true, because the in-proc node cannot be detoured:
// To properly report file access, we need to disable the in-proc node which won't be detoured._buildParameters!.DisableInProcNode=true;
Scheduler.CreateNewNodeIfPossible (src/Build/BackEnd/Components/Scheduler/Scheduler.cs) gives multithreaded mode an out-of-proc node budget of zero, because MT mode is supposed to service everything with in-proc thread nodes:
intmaxInProcNodeCount=_componentHost.BuildParameters.MultiThreaded?_componentHost.BuildParameters.MaxNodeCount:1;intavailableNodesWithInProcAffinity=maxInProcNodeCount-_currentInProcNodeCount;intavailableNodesWithOutOfProcAffinity=_componentHost.BuildParameters.MultiThreaded?0:_componentHost.BuildParameters.MaxNodeCount-_currentOutOfProcNodeCount;
With DisableInProcNode == true, NodeAffinity.Any requests are pushed down the out-of-proc branch, but the out-of-proc budget is 0, so no CreateNode response is ever produced and ScheduleUnassignedRequests throws.
Impact
Cache implementations built on the project-cache plugin API (for example Microsoft.MSBuildCache) need -reportfileaccesses for cache population, since ProjectCacheService only registers ProjectCachePluginBase.HandleFileAccess / HandleProcess handlers when BuildParameters.ReportFileAccesses is set. Those builds therefore cannot opt into -mt at all today — independent of the deserialization defect in #14824.
Suggested fix
Short term, since both switches are experimental and opt-in, detect the combination up front (in BuildManager.BeginBuild or during command-line switch processing) and fail with a specific, localized error instead of an internal error.
Longer term this needs a design decision: file-access attribution today relies on DetouredNodeLauncher detouring a launched worker process, whereas MT thread nodes live inside the scheduler process and are never launched through NodeLauncher. Reporting file accesses for thread nodes would need a different attribution mechanism before the two features can coexist.
Summary
-mt(experimental multithreaded MSBuild) and-reportfileaccessescannot be used together. Combining them fails the build immediately with an internal error, before any project work happens:This was found while investigating #14824.
Steps to reproduce
Any project at all, using the x64 .NET Framework MSBuild (file-access reporting is only compiled into the
net472build, and it additionally requires x64):Actual behavior
MSB1025/MSB0001: We failed to request a node to be created.Either switch on its own works fine (
-mtalone printshello;-reportfileaccessesalone builds normally).Expected behavior
Either the combination works, or MSBuild reports a clear, actionable error explaining that the two switches are mutually exclusive.
Root cause
The two features make contradictory demands on node affinity:
BuildManager.EnableDetouredNodeLauncher(src/Build/BackEnd/BuildManager/BuildManager.cs) sets_buildParameters.DisableInProcNode = true, because the in-proc node cannot be detoured:Scheduler.CreateNewNodeIfPossible(src/Build/BackEnd/Components/Scheduler/Scheduler.cs) gives multithreaded mode an out-of-proc node budget of zero, because MT mode is supposed to service everything with in-proc thread nodes:With
DisableInProcNode == true,NodeAffinity.Anyrequests are pushed down the out-of-proc branch, but the out-of-proc budget is0, so noCreateNoderesponse is ever produced andScheduleUnassignedRequeststhrows.Impact
Cache implementations built on the project-cache plugin API (for example
Microsoft.MSBuildCache) need-reportfileaccessesfor cache population, sinceProjectCacheServiceonly registersProjectCachePluginBase.HandleFileAccess/HandleProcesshandlers whenBuildParameters.ReportFileAccessesis set. Those builds therefore cannot opt into-mtat all today — independent of the deserialization defect in #14824.Suggested fix
Short term, since both switches are experimental and opt-in, detect the combination up front (in
BuildManager.BeginBuildor during command-line switch processing) and fail with a specific, localized error instead of an internal error.Longer term this needs a design decision: file-access attribution today relies on
DetouredNodeLauncherdetouring a launched worker process, whereas MT thread nodes live inside the scheduler process and are never launched throughNodeLauncher. Reporting file accesses for thread nodes would need a different attribution mechanism before the two features can coexist.