Skip to content

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

Description

@ChadNedzlek

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions