dotnet / dotnet/msbuild

Multithreaded MSBuild (-mt) is incompatible with -reportfileaccesses: MSB0001 'We failed to request a node to be created'

Open
#14,825 0 comments 0 reactions 0 assignees View on GitHub
Area: Multithreaded Priority:1 triaged
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.