An MSBuild worker node crashed mid-build, so MSBuild reports it stopped unexpectedly (often MSB4166, "child node exited prematurely"). On CI this is frequently an out-of-memory kill of a build node.
What this error means
The build aborts with "The build stopped unexpectedly" or "MSB4166: Child node ... exited prematurely", sometimes intermittently. It can correlate with heavy parallel builds or large analyzers on a memory-constrained runner.
MSBuild output
error MSB4166: Child node "2" exited prematurely. Shutting down.
The build stopped unexpectedly because of an internal failure.
Common causes
A build worker was OOM-killed
Parallel MSBuild nodes each consume memory; on a small runner a large solution plus analyzers can exhaust RAM and the OS kills a node.
A faulting task, analyzer, or source generator
A crashing analyzer or source generator can take down a node, producing an internal-failure message rather than a normal compiler error.
How to fix it
Reduce build parallelism / give more memory
Lower the node count or run on a larger runner so nodes don’t exhaust memory.
Terminal
dotnet build -m:1 -c Release
# or cap MSBuild nodes
export MSBUILDNODECOUNT=2
Isolate a crashing analyzer or generator
Build with -bl and inspect the binlog for the last task before the node died.
Temporarily disable suspect analyzers/source generators to confirm the culprit.
Update or pin the offending analyzer package to a fixed version.
How to prevent it
Right-size runners for large solutions and analyzer-heavy builds.
Cap MSBuild node count on memory-constrained runners.
Keep analyzers and source generators updated to avoid known crashes.
Frequently asked questions
What causes ""The build stopped unexpectedly""?
Parallel MSBuild nodes each consume memory; on a small runner a large solution plus analyzers can exhaust RAM and the OS kills a node.
How do I fix "The build stopped unexpectedly"?
Lower the node count or run on a larger runner so nodes don’t exhaust memory.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.