Shortly after posting about my tips to fix broken builds, I was in for another bug hunt that took a few hours to resolve. This time it wasn’t the build itself that failed, but the package that came out of it. For some reason, the application crashed instantly on a missing DLL error you know and hate in .NET.
Usually it means a Nuget package conflict. Cleaning the build sometimes helps, but not in this case. We are talking about system DLL’s here, so you know you’re in trouble when that happens.
I was getting the following exception at runtime on a .NET Core app. It wasn’t always the same DLL. But every time it was a system DLL like System.Collections, System.Collection.Generic, System.Linq, etc.
Unhandled exception. System.IO.FileLoadException: Could not load file or assembly 'System.Collections, Version=126.96.36.199, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The located assembly's manifest definition does not match the assembly reference. (0x80131040) File name: 'System.Collections, Version=188.8.131.52, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' at Microsoft.Extensions.DependencyInjection.ServiceCollection..ctor()
When checking the package files, the wrong version of the DLL was in the output, compared to the version number I was seeing in the solution, so the error message was correct. The problem was, why does the build pick the wrong DLL version? My local build output was fine however, so that just adds to the mystery.
The special bit about this project is that it also used a .NET Framework DLL. It was doing some .NET Standard magic in the build.
- The project has a mix of .NET Core / .NET Standard / .NET Framework projects or Nuget packages.
- You are building a self contained application (so all DLL’s are copied in the output folder).
- Seemingly random 0x80131040 errors when I try to run my deployed .NET Core app on system DLL’s.
- Different builds give errors on different DLL’s, but they are always system DLL’s.
- A local
dotnet publishworks, but the output from the build server doesn’t run.
The fix turned out to be stupefyingly simple. I was build the .sln file for my project in the CI pipeline, instead of the .csproj file for the console application itself.
Apparently things go wrong at build time and the wrong DLL’s are copied into your output folder, giving you the exceptions above on startup.
The reason why the same
dotnet publish command works locally is probably because I have version 5 of the dotnet tool on my local machine, due to Visual Studio. On the build server version 3.1 is installed, from the 3.1 SDK. My guess is that the 3.1 version handles mixed solutions differently than the dotnet 5 version.