sdk
sdk copied to clipboard
dotnet watch run or build suddenly started failing with Sdk.Web, > 8.0.206 and Paket.
This is related to this issue, around a breaking change somewhere after .NET 8.0.206 that is impacted (as far as I can tell) from the following convergence:
- You are using the
Microsoft.NET.Sdk.WebSDK. - You are using an SDK later than 8.0.206 (I've used up to 401 and can reliably reproduce this).
- You are using Paket as your .NET package management client.
This issue is not confined to F#. It also impacts C# projects.
If all of these things are true and you dotnet watch build or run from the folder of the project, things go wrong. I suspect it's something that's changed since 8.0.206 (or the Sdk.Web) that has somehow broken Paket.
We have seen this with multiple customers of SAFE Stack, which uses Paket and ASP .NET Core - when people upgraded to 8.0.3xx, things started going wrong with no code changes at all.
This repository contains a working reproduction of the issue using F#, whilst this repository contains an even simpler repro of the issue using C#.
Here are some steps to reproduce:
- Install a version of .NET 8.0 after 8.0.206 (I'm using 8.0.401).
- Make a clean folder and
cdto it. dotnet new globaljson- Set it to e.g.
{
"sdk": {
"version": "8.0.401"
}
}
dotnet new console -lang F#dotnet tool install paket --create-manifest-if-neededdotnet paket add FSharp.Core- Change the SDK in the project file.
Now, observe the following behaviours:
dotnet watch build ❌
dotnet watch � Started
Determining projects to restore...
Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
File name: 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
at System.Reflection.RuntimeAssembly.GetType(QCallAssembly assembly, String name, Boolean throwOnError, Boolean ignoreCase, ObjectHandleOnStack type, ObjectHandleOnStack keepAlive, ObjectHandleOnStack assemblyLoadContext)
at System.Reflection.RuntimeAssembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase)
at System.Reflection.Assembly.GetType(String name, Boolean throwOnError)
at System.StartupHookProvider.CallStartupHook(StartupHookNameOrPath startupHook)
at System.StartupHookProvider.ProcessStartupHooks()
D:\code\runthru\.paket\Paket.Restore.targets(171,3): error MSB3073: The command "dotnet paket restore" exited with code -532462766. [D:\code\runthru\runthru.fsproj]
Build FAILED.
dotnet watch run ❌
error MSB3073: The command "dotnet paket restore" exited with code -532462766
Workarounds
- Don't use
watch;dotnet buildanddotnet runon their own work. ✅ - Change
global.jsonto pin to 8.0.206. ✅ - Change the
fsprojSDK toMicrosoft.NET.Sdk✅ - Add
--no-restoreto eitherwatch runorwatch build. ✅
Observations
- Something has changed in the behaviour of
dotnet watchafter 8.0.206 of the SDK. That's the last working version of .NET 8 that I could find. - There's evidently a difference in behaviour from watch and non-watch versions of
dotnet buildanddotnet run. This shouldn't be the case. - It's somehow linked to the Web SDK. The regular SDK works fine.
cc: @baronfel - he has been unable to reproduce this on his machine at all :-(
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.
I was having the same issue with dotnet watch run and I saw the following in Event Viewer:
Application: dotnet.exe
CoreCLR Version: 4.700.22.55902
.NET Core Version: 3.1.32
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
File name: 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
at System.Reflection.RuntimeAssembly.GetType(QCallAssembly assembly, String name, Boolean throwOnError, Boolean ignoreCase, ObjectHandleOnStack type, ObjectHandleOnStack keepAlive, ObjectHandleOnStack assemblyLoadContext)
at System.Reflection.RuntimeAssembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase)
at System.Reflection.Assembly.GetType(String name, Boolean throwOnError)
at System.StartupHookProvider.CallStartupHook(StartupHookNameOrPath startupHook)
at System.StartupHookProvider.ProcessStartupHooks()
Along with sdk versions 6 and 8, I had sdk 3.1 installed, as part of VS2019, so I uninstalled it (using dotnet-core-uninstall which advised that the uninstall would break VS2019) and now dotnet watch run and dotnet build appear to be working normally with a global.json that specifies sdk 8.0.403.
@kevkov that's really helpful. I was able to do the same by also removing .NET 5 completely from my machine. This is taken from Event Viewer:
Application: dotnet.exe
CoreCLR Version: 5.0.1722.21314
.NET Version: 5.0.17
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
File name: 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
at System.Reflection.RuntimeAssembly.GetType(QCallAssembly assembly, String name, Boolean throwOnError, Boolean ignoreCase, ObjectHandleOnStack type, ObjectHandleOnStack keepAlive, ObjectHandleOnStack assemblyLoadContext)
at System.Reflection.RuntimeAssembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase)
at System.Reflection.Assembly.GetType(String name, Boolean throwOnError)
at System.StartupHookProvider.CallStartupHook(StartupHookNameOrPath startupHook)
at System.StartupHookProvider.ProcessStartupHooks()
So the real issue here - and this explains @baronfel why it doesn't happen on some people's machines - appears to be that other versions of .NET are somehow being used with running dotnet watch. The repository I created clearly specifies .NET 8 and yet removing .NET 5 somehow fixes this issue.
This is worrying as .NET versions are supposed to be safely installed side-by-side.
Dove deeper into this, Paket seems to target .NET Core 3.1 still, which hasn't been supported in years. The bigger issue seems to be that it also includes a self contained framework, which AFAIK isn't supported at all for dotnet tools.
Both of the above errors fail to note the next line: error MSB3073: The command "dotnet paket restore" exited with code -532462766.
#9564 is the most relevant issue
A self contained application is a runnable app that carries a copy of the .NET Core Runtime inside itself. Global tools doesn't support this for a few reasons - we assume the user of the package wants to decide what .NET Core Runtime to use within the targeted frameworks specified by the author. Self contained apps are comparatively giant (because they contain the core). More importantly though, current global tools rely on a shim that provides the app host to run the tool.
That shim is likely why this is failing, but its also not designed around usage of self contained tools.
If you have a self contained tool it needs to be executed without calling dotnet paket and should be instead called directly using the full path to the Paket exe. (The above error was from the execution of dotnet paket restore instead of paket restore).
Paket's scenario is entirely outside the supported use cases with dotnet tools from what I can tell, and even though this issue is old; AFAIK none of this has changed. Trying to pack a new tool even today that specified self contained results in a build error: error NETSDK1053: Pack as tool does not support self contained..
It may be better to open an issue in the Paket repository and get Paket on a move to remove the runtime from the tool package and get under a supported scenario for dotnet tools; or start a request for supporting self contained tools within the SDK (though based on the existing issue, this may still not be a priority).