sdk icon indicating copy to clipboard operation
sdk copied to clipboard

error NU1004: The package reference Microsoft.NET.ILLink.Tasks version has changed from [8.0.14, ) to [8.0.15, ).

Open dazinator opened this issue 8 months ago • 10 comments

Description

We use nuget locked mode (package lock files).

Our dev team has dotnet SDK 8.0.407 installed currently, and a few days ago, dotnet SDK 8.0.408 (8.0.15) was released. We see this behaviour

  • There is one nuget dependency that seems to make its way into the package.lock.json that is actually supplied by whatever version of the SDK you build the solution with. So in our case - this is the version of the dependency that makes its way into the lock file when the developers build with dotnet SDK 8.0.407:
     "Microsoft.NET.ILLink.Tasks": {
    "type": "Direct",
    "requested": "[8.0.14, )",
    "resolved": "8.0.14",
    "contentHash": "4U2fd7PexNKrK5ZqfqIcXZj9/lRRjFsLgA/pxuFQTuGQuLYP/+7yACz/j7EmWbEj/fspOf4mafi/vHIy/rKDzQ=="
     },
    

However our CI/CD server installs the sdk based on the global.json in our repo, which allows later patch versions - this means as of the new dotnetr sdk release a few days ago, CI builds use dotnet SDK 8.0.408`

  • The build then fails because

    error NU1004: The package reference Microsoft.NET.ILLink.Tasks version has changed from [8.0.14, ) to [8.0.15, ).

We have never hit this problem prior to dotnet 8. Having a dependency thats "hard coded" from the dotnet SDK you are restoring with, seems to be at odds with the package lock feature, and a global.json that allows newer dotnet SDK patches to build the solution.

Reproduction Steps

As explained

  • create a blazor wasm application project using dotnet SDK 8.0.407 and enable nuget package lock feature - build it, and commit the package.lock.json file
  • on a different machine (or build server) with dotnet SDK 8.0.408 installed, restore the solution with locked mode.
  • you'll hit the error

Expected behavior

I'd expect that for dependencies to be meaningfully captured in a lock file that they would be fixed at the point of build when the lock file is produced. If their are environmental dependencies that sneak into the lock file, and that actually depend on the precise patch version of the SDK that you restore with (8.0.407 vs 8.0.408) this is not obvious to determine at the time, but opens the way for any SDK patch to (perhaps inadvertently in this case?) break all builds accross our organisation and CI / CD servers.. I just didn't expect for a minor patch to the SDK to break package restore.

Actual behavior

As discussed, this new paradigm makes package lock mode more fragile and means that an SDK patch breaks builds - which devalues global.json roll forward feature. The more troublesome issue is it forces that the CI server and all developers must all upgrade to the exact same SDK version together, otherwise they will be in a situation where eachothers dotnet restore will fail.

Regression?

Yes this is a regression, I did not see this behaviour in prior dotnet versions - and we all updated out dotnet SDK's many times, and the CI server also had slightly differing versions as we updated seperately over time - did not see any such issues.

Known Workarounds

SDK has to be aligned accross all local developers and CI servers at the same time should any of them want to roll forward to a new patch version of the SDK and locked mode is being used.

Configuration

No response

Other information

No response

dazinator avatar Apr 11 '25 12:04 dazinator

Tagging subscribers to this area: @dotnet/illink See info in area-owners.md if you want to be subscribed.

This looks to be a bug in the SDK. The ILLink.Tasks package is an implict package and shouldn't be included in the lock file.

agocke avatar May 02 '25 02:05 agocke

@nkolev92 @baronfel What is our guidance in cases like this? Should the lock file include implicitly supplied package downloads? Similar to discussions we were having yesterday about lock files.

marcpopMSFT avatar Jun 24 '25 18:06 marcpopMSFT

  • @sbomer as well. My understanding was that this was the recommended way to pull in extra resources for publish in the sdk. If it’s not, we could explore another deployment option.

agocke avatar Jun 24 '25 20:06 agocke

It's the recommended way today, but it is a gap in the overall NuGet lockfile story. Our current recommendation for users that use lock files is to also lock their SDK versions via global.json with no rollforward, so they their entire toolchain stays in lockstep.

baronfel avatar Jun 24 '25 20:06 baronfel

I just now realized I started a comment and never finished it.

We have a tracking issue for PackageDownload in https://github.com/nuget/home/issues/7724.

I think the Microsoft.NET.ILLink.Tasks is marked as a PackageReference in this case. The current design for lock files is that auto referenced packages are part of the lock file. The idea was that the repeatability of the build is dependent on using the same tooling. (what @baronfel said :) )

nkolev92 avatar Jun 26 '25 21:06 nkolev92

Ah yeah - ILLink is special amongst many of the other implicit packages because we rely on loading the props/targets from it to overwrite some of the defaults that the SDK ships with. Everything else can be a PackageDownload because we just need access to the bits.

ILLink could become a PackageDownload as well, if we did some additional computing of paths to do the Imports ourselves in the SDK.

baronfel avatar Jun 26 '25 21:06 baronfel

What is the current status of this? Can we expect a fix soon? Or is there maybe a workaround?

This is currently preventing us from using lock files. 😞

tnotheis avatar Dec 11 '25 15:12 tnotheis

@tnotheis Given that Microsoft.NET.ILLink.Tasks is being automatically added as a PackageReference, at this point you need to use the same .NET SDK version locally and on the CI.

nkolev92 avatar Dec 11 '25 17:12 nkolev92

It's the recommended way today, but it is a gap in the overall NuGet lockfile story. Our current recommendation for users that use lock files is to also lock their SDK versions via global.json with no rollforward, so they their entire toolchain stays in lockstep.

This was news to me. I don't think that recommendation is present in the docs for lock files. Could it be added there?

Frulfump avatar Dec 11 '25 18:12 Frulfump