GitVersion: MSBUILD : Task factory warning NMSBT010: There is a mismatch between SDK NuGet version (4.8.1) and the NuGet version the task factory was compiled against (4.8.0). There might occur some exotic errors.

Hi,

I have just updated a .NET Core project to Gitversion.Task 4.0.0. It seems to be working fine and it’s nice to see this now working with the .NET Core SDK enabling us to call dotnet build and have versioning work. Great job!

However, there are some warnings generated by the tool. Namely:

MSBUILD : Task factory warning NMSBT010: There is a mismatch between SDK NuGet version (4.8.1) and the NuGet version the task factory was compiled against (4.8.0). There might occur some exotic errors.

This is only a warning and doesn’t cause the build to fail and as far as I can tell there are no issues with the version numbers being generated. However, I did notice #1467 and I wonder if this NuGet version mismatch is going to be a problem every time there is an update to the NuGet version in the .NET Core SDK. I do not have any experience building tools for the .NET Core SDK so I have no idea what the best practice is here for avoiding these kinds of warnings. I can imagine it would be a pain to have to release this library every time NuGet is updated in the .NET Core SDK.

For reference the .NET Core SDK version I am using is 2.1.403. Our Travis build uses the same SDK version and reports the same warnings, however AppVeyor is using 2.1.402 and doesn’t report any warnings.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 3
  • Comments: 46 (23 by maintainers)

Commits related to this issue

Most upvoted comments

I’ve released a new version of the task factory, which uses smarter logic to choose version when there is no exact match. It now defaults to use 4.8.0 NuGet on 2.1.403 SDK instead of 4.9.0. Furthermore, there is now ability to completely override the version it uses by specifying UTILPACK_NUGET_VERSION environment variable.

Let me know how it goes - it successfully worked for me in my tests. It still prints out a message in any version mismatches, just not a warning if only build version is mismatched.

I think I’m still getting issues related to this - using 4.0.1-beta1.50 the build works fine on SDK 2.1.500… BUT when using vscode and omnisharp 1.32.8 I’m getting failures - meaning that intellisense etc isn’t working for me. On windows btw.

Exception is:

[info]: OmniSharp.MSBuild.ProjectManager
        Loading project: c:\Source\xxxxxxxx\xxxxxx.csproj
Exception when creating task: System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
File name: 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
   at UtilPack.NuGet.AssemblyLoading.NuGetRestorerWrapper.ResolveNuGetPackageAssemblies(String[] packageID, String[] packageVersion, MarshaledResultSetter`1 setter)
   at UtilPack.NuGet.AssemblyLoading.NuGetAssemblyResolverImpl.UseResolver(String[] packageIDs, String[] packageVersions)
   at UtilPack.NuGet.AssemblyLoading.NuGetAssemblyResolverImpl.<LoadNuGetAssemblies>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at E_UtilPack.<LoadNuGetAssembly>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at UtilPack.NuGet.MSBuild.NuGetTaskRunnerFactory.LoadTaskType(String taskTypeName, NuGetAssemblyResolver resolver, String packageID, String packageVersion, String assemblyPath, ConstructorInfo& taskConstructor, Object[]& constructorArguments, Boolean& usesDynamicLoading)
   at UtilPack.NuGet.MSBuild.TaskReferenceCreator.CreateTaskReferenceHolder(String taskTypeName, NuGetAssemblyResolver resolver, String packageID, String packageVersion, String assemblyPath, String msbuildFrameworkAssemblyName, ResolverLogger logger)
   at UtilPack.NuGet.MSBuild.TaskReferenceCreator.CreateTaskReferenceHolder(String taskTypeName, NuGetAssemblyResolver resolver, String packageID, String packageVersion, String assemblyPath, String msbuildFrameworkAssemblyName, ResolverLogger logger)
   at UtilPack.NuGet.MSBuild.NuGetTaskRunnerFactory.CreateExecutionHelper(String taskName, XElement taskBodyElement, String taskPackageID, String taskPackageVersion, String taskAssemblyFullPath, String taskAssemblyPathHint, BoundRestoreCommandUser restorer, ResolverLogger resolverLogger, GetFileItemsDelegate getFiles, String assemblyCopyTargetFolder, AppDomainSetup& appDomainSetup)
   at UtilPack.NuGet.MSBuild.NuGetTaskRunnerFactory.<>c__DisplayClass36_5.<Initialize>b__7()

WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].

[fail]: OmniSharp.MSBuild.ProjectLoader
        Exception in initialization: System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
File name: 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
   at UtilPack.NuGet.AssemblyLoading.NuGetRestorerWrapper.ResolveNuGetPackageAssemblies(String[] packageID, String[] packageVersion, MarshaledResultSetter`1 setter)
   at UtilPack.NuGet.AssemblyLoading.NuGetAssemblyResolverImpl.UseResolver(String[] packageIDs, String[] packageVersions)
   at UtilPack.NuGet.AssemblyLoading.NuGetAssemblyResolverImpl.<LoadNuGetAssemblies>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at E_UtilPack.<LoadNuGetAssembly>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at UtilPack.NuGet.MSBuild.NuGetTaskRunnerFactory.LoadTaskType(String taskTypeName, NuGetAssemblyResolver resolver, String packageID, String packageVersion, String assemblyPath, ConstructorInfo& taskConstructor, Object[]& constructorArguments, Boolean& usesDynamicLoading)
   at UtilPack.NuGet.MSBuild.TaskReferenceCreator.CreateTaskReferenceHolder(String taskTypeName, NuGetAssemblyResolver resolver, String packageID, String packageVersion, String assemblyPath, String msbuildFrameworkAssemblyName, ResolverLogger logger)
   at UtilPack.NuGet.MSBuild.TaskReferenceCreator.CreateTaskReferenceHolder(String taskTypeName, NuGetAssemblyResolver resolver, String packageID, String packageVersion, String assemblyPath, String msbuildFrameworkAssemblyName, ResolverLogger logger)
   at UtilPack.NuGet.MSBuild.NuGetTaskRunnerFactory.CreateExecutionHelper(String taskName, XElement taskBodyElement, String taskPackageID, String taskPackageVersion, String taskAssemblyFullPath, String taskAssemblyPathHint, BoundRestoreCommandUser restorer, ResolverLogger resolverLogger, GetFileItemsDelegate getFiles, String assemblyCopyTargetFolder, AppDomainSetup& appDomainSetup)
   at UtilPack.NuGet.MSBuild.NuGetTaskRunnerFactory.<>c__DisplayClass36_5.<Initialize>b__7()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at UtilPack.NuGet.MSBuild.NuGetTaskRunnerFactory.Initialize(String taskName, IDictionary`2 parameterGroup, String taskBody, IBuildEngine taskFactoryLoggingHost)

WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].

[fail]: OmniSharp.MSBuild.ProjectLoader
        The task factory "UtilPack.NuGet.MSBuild.NuGetTaskRunnerFactory" could not be loaded from the assembly "C:\Users\kiera\.nuget\packages\utilpack.nuget.msbuild\2.9.1\build\\net46\UtilPack.NuGet.MSBuild.dll". Could not load file or assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.

@kieranbenton : I develop on a mac using the dotnet sdk (local install) using JetBrains Rider IDE. For CI builds I’m using CircleCI using the microsoft/dotnet-sdk docker image for building. Happy to share more details if helpful for you!

@arturcic 4.0.1-beta1-50 works fine for me with microsoft/dotnet-sdk:latest so all good!

@kieranbenton can you raise the issue with utilpack and omnisharp over here: https://github.com/stazz/UtilPack

Thanks, that is suspiciously convenient looking site by MS! 😉 I’ll try to come up with something on sunday!

Hi, I now seeing some errors. Although I should start by pointing out that I’m still using version 2.1.403 of the .NET SDK, so please let me know if this fix is only expected to work against the latest .NET SDK.

Now the first error I encountered was:

C:\Users\<username>\.nuget\packages\gitversiontask\4.0.1-beta1-49\build\functionality\GitVersionBuild.targets(6,5): error MSB4175: The task factory "UtilPack.NuGet.MSBuild.NuGetTaskRunnerFactory" could not be loaded from the assembly "C:\Users\m.<username>\.nuget\packages\utilpack.nuget.msbuild\2.9.0\build\\netcoreapp1.1\UtilPack.NuGet.MSBuild.dll". Assembly with same name is already loaded [J:\Workspace\<MyApp>\src\<Proj2>\<Proj2>.csproj]

I reference GitVersion.Task in each project of the solution as this particular solution outputs multiple packages. So I tried removing it from all but one project in the solution and then it managed to get a bit further. However it still produced the following warning and and error:

MSBUILD : Task factory warning NMSBT010: There is a mismatch between SDK NuGet version (4.8.1) and the NuGet version the task factory was compiled against (4.9.0). There might occur some exotic errors. [J:\Workspace\<MyApp>\src\<Proj1>\<Proj1>.csproj]
C:\Users\<username>\.nuget\packages\gitversiontask\4.0.1-beta1-49\build\functionality\GitVersionBuild.targets(6,5): error MSB4175: The task factory "UtilPack.NuGet.MSBuild.NuGetTaskRunnerFactory" could not be loaded from the assembly "C:\Users\<username>\.nuget\packages\utilpack.nuget.msbuild\2.9.0\build\\netcoreapp1.1\UtilPack.NuGet.MSBuild.dll". Could not load file or assembly 'NuGet.ProjectModel, Version=4.9.0.6, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified. [J:\Workspace\<MyApp>\src\<Proj1>\<Proj1>.csproj]

The warning makes me think that this is because I need to update to the latest .NET SDK. Is that correct?

This should hopefully be fixed in the latest beta meaning if you update from nuget.org, you should no longer need to pin the sdk version. I’ll leave this open until someone can confirm this.

With VS2017 15.9, we get SDK 2.1.500 by default, meaning GitVersionTask by default won’t work.

Workaround

Place a Globals.json at some parent (f.ex. project or solution root), with contents:

{
  "sdk": {
    "version": "2.1.403"
  }
}

Remove it when GitVersionTask is updated

EDIT: One may also include, next to <PackageReference Include="GitVersionTask" Version="4.0.1-beta*" PrivateAssets="All" /> a <PackageReference Include="UtilPack.NuGet.MSBuild" Version="2.9.0" PrivateAssets="All" /> to force the newer version from @stazz

Hi all,

Yes, the UtilPack task factory, in .NET Core version uses reflection at runtime to detect the version of NuGet.Commands and then choose the actual task factory implementation compiled against that version. The warning that you see is emitted when it can’t find a match - meaning that the user’s NuGet.Commands assembly is typically newer than the newest one that the task factory was compiled against.

The obvious solution would be to lock down the NuGet version and ship the assemblies with the task factory. That is actually how it is done in .NET Desktop version. However, on .NET Core, when one invokes dotnet build, everything that is in C:\Program Files\dotnet\sdk\<version> folder (on Windows, on Linux it’s prolly a bit different, but you get the idea) is marked as “trusted framework assembly”. That folder contains all the NuGet assemblies, and once they become trusted framework assemblies, they are not manipulatable via any custom AssemblyLoadContext implementations (at least when I was investigating this few months ago). So there is no way to lock down NuGet version on .NET Core when using dotnet msbuild and it loads the task factory. This leads to the unpleasant reality that @Choc13 correctly observed: every time the user updates his or hers .NET Core SDK, things might break, and I have to re-release the version of task factory which has binary compatibility with the newer NuGet packages.

One solution could be to use global.json to lock down the .NET SDK version to a specific one. That would require most likely custom build scripts within the GitVersionTask that would emit such a file before actual build, or rely on user to provide such a file by himself. Not exactly elegant solution, but is an option. More documentation is available.

Another solution could be using the NuGetUtils.Tool.Exec/ .NET Core Global Tool. Since the global tools don’t rely to be ran under dotnet build command, the tool is able to in this case, lock down the NuGet assembly version, thus eliminating this whole problem. The downside is that none of the MSBuild-specific stuff (tasks, logs, etc) is present, so you’d need to replace that with something else. Furthermore, the user of the GitVersionTask would need to have the tool installed, and it only works in .NET Core environment.

To be honest, I don’t have a clear solution for this. But I hope I’ve provided some starting points for a discussion about this.