sdk icon indicating copy to clipboard operation
sdk copied to clipboard

dotnet watch run or build suddenly started failing with Sdk.Web, > 8.0.206 and Paket.

Open isaacabraham opened this issue 1 year ago • 2 comments

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:

  1. You are using the Microsoft.NET.Sdk.Web SDK.
  2. You are using an SDK later than 8.0.206 (I've used up to 401 and can reliably reproduce this).
  3. 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:

  1. Install a version of .NET 8.0 after 8.0.206 (I'm using 8.0.401).
  2. Make a clean folder and cd to it.
  3. dotnet new globaljson
  4. Set it to e.g.
{
    "sdk": {
        "version": "8.0.401"
    }
}
  1. dotnet new console -lang F#
  2. dotnet tool install paket --create-manifest-if-needed
  3. dotnet paket add FSharp.Core
  4. 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 build and dotnet run on their own work. ✅
  • Change global.json to pin to 8.0.206. ✅
  • Change the fsproj SDK to Microsoft.NET.Sdk
  • Add --no-restore to either watch run or watch build. ✅

Observations

  • Something has changed in the behaviour of dotnet watch after 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 build and dotnet 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 :-(

isaacabraham avatar Sep 16 '24 15:09 isaacabraham

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.

ghost avatar Sep 16 '24 15:09 ghost

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.

ghost avatar Sep 16 '24 15:09 ghost

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 avatar Oct 25 '24 12:10 kevkov

@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.

isaacabraham avatar Dec 24 '24 21:12 isaacabraham

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).

andrewbabbittdev avatar Jan 07 '25 13:01 andrewbabbittdev