dependabot / dependabot/dependabot-core

nuget: >2 TargetFrameworks routes into a restore mode that hard-crashes on a known NuGet NRE

Open
#16,136 0 comments 0 reactions 0 assignees View on GitHub
L: dotnet:dotnet-sdk L: dotnet:nuget
Dominant language
Ruby
Stars
5.8k
Forks
1.5k
Avg merge
2d 18h
Merged PRs (30d)
149

Description

## Summary

`SdkProjectDiscovery.DiscoverAsync` routes any project reporting more than `MaximumParallelTargetFrameworkRestores` (2) target frameworks into an "individual TFM restore" mode. That mode invokes restore with `/p:TargetFramework={tfm}` set explicitly, once per framework:

https://github.com/dependabot/dependabot-core/blob/main/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs

Passing an explicit `TargetFramework` property to a restore using static graph evaluation trips a long-standing NuGet bug: [NuGet/Home#11761](https://github.com/NuGet/Home/issues/11761), open since 2022, an NRE in `MSBuildStaticGraphRestore`. The crash is triggered purely by the explicit property. It reproduces identically on a plain single-target project given the same override, with no multi-targeting involved at all.

## Repro

Any project with 3+ `TargetFrameworks` and central package management (`Directory.Packages.props`) hits this on every Dependabot nuget job. Reproduced independent of Dependabot with a plain SDK-style project:

```
dotnet restore SomeProject.csproj -p:TargetFramework=net10.0
```

This crashes with the identical stack trace dependabot-core's nuget jobs report:

```
NuGet.RestoreEx.targets(19,5): error : Object reference not set to an instance of an object.
at NuGet.Build.Tasks.Console.MSBuildStaticGraphRestore...
```

## Impact

Every nuget update job for a repo with a 3+-TFM project effectively never completes discovery. It burns through this crash repeatedly (each hit logs a WARN and continues) across every project that references the multi-targeted one, until GitHub Actions kills the job on timeout. In our case that's ~55 minutes per run with no successful completion.

## Possible fix direction

`dotnet build --framework {tfm}` is the SDK's documented, supported entry point for pinning one TFM of a multi-targeted project. It dispatches through the SDK's supported inner/outer-build machinery and does not reproduce the crash (confirmed locally). Worth considering for the individual-TFM restore path, if the discovery step can tolerate the fuller build it triggers.

Contributor guide

Open the contributing guide

Research direction

Start in NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs, especially the individual-TFM restore path selected above two target frameworks. Reproduce the failure with `dotnet restore SomeProject.csproj -p:TargetFramework=net10.0` and compare it with the documented `dotnet build --framework {tfm}` entry point. Done means discovery no longer repeatedly hard-crashes on multi-targeted projects and can complete its restore work.

Written by the indexing model from the issue text.

Assessment

Domain
build-system, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.