Multithreaded MSBuild (-mt) is incompatible with -reportfileaccesses: MSB0001 'We failed to request a node to be created'
- Dominant language
- C#
- Stars
- 5.5k
- Forks
- 1.5k
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 141
Description
### 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:
```text
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):
```xml
```
```
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:
1. `BuildManager.EnableDetouredNodeLauncher` (`src/Build/BackEnd/BuildManager/BuildManager.cs`) sets `_buildParameters.DisableInProcNode = true`, because the in-proc node cannot be detoured:
```csharp
// To properly report file access, we need to disable the in-proc node which won't be detoured.
_buildParameters!.DisableInProcNode = true;
```
2. `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:
```csharp
int maxInProcNodeCount = _componentHost.BuildParameters.MultiThreaded ? _componentHost.BuildParameters.MaxNodeCount : 1;
int availableNodesWithInProcAffinity = maxInProcNodeCount - _currentInProcNodeCount;
int availableNodesWithOutOfProcAffinity = _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.
Contributor guide
No contributing guide indexed for this repository
Research direction
Reproduce with the trivial project and `MSBuild.exe trivial.proj -mt -reportfileaccesses`, then read `BuildManager.EnableDetouredNodeLauncher` in `src/Build/BackEnd/BuildManager/BuildManager.cs` and `Scheduler.CreateNewNodeIfPossible` in `src/Build/BackEnd/Components/Scheduler/Scheduler.cs`. Compare the behavior with each switch alone; done means the combination either works or returns a specific, localized, actionable error instead of MSB0001.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- build-system, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100