diff --git a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs
index 49fd4afb9bb..a0ff6c0548c 100644
--- a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs
+++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs
@@ -1381,4 +1381,57 @@ await TestDiscoveryAsync(
}
);
}
+
+ // If the "Restore" target is invoked and $(RestoreUseStaticGraphEvaluation) is set to true, NuGet can throw
+ // a NullReferenceException.
+ // https://github.com/NuGet/Home/issues/11761#issuecomment-1105218996
+ [Fact]
+ public async Task NullReferenceExceptionFromNuGetRestoreIsWorkedAround()
+ {
+ await TestDiscoveryAsync(
+ packages: [
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.2.3", "net8.0"),
+ ],
+ experimentsManager: new ExperimentsManager() { UseDirectDiscovery = true },
+ workspacePath: "",
+ files: [
+ ("project.csproj", """
+
+
+ net8.0
+ true
+
+
+
+
+
+ """),
+ // a pattern seen in the wild; always run restore
+ ("Directory.Build.rsp", """
+ /Restore
+ """)
+ ],
+ expectedResult: new()
+ {
+ Path = "",
+ Projects = [
+ new()
+ {
+ FilePath = "project.csproj",
+ TargetFrameworks = ["net8.0"],
+ Dependencies = [
+ new("Some.Package", "1.2.3", DependencyType.PackageReference, TargetFrameworks: ["net8.0"], IsDirect: true)
+ ],
+ Properties = [
+ new("RestoreUseStaticGraphEvaluation", "true", "project.csproj"),
+ new("TargetFramework", "net8.0", "project.csproj"),
+ ],
+ ReferencedProjectPaths = [],
+ ImportedFiles = [],
+ AdditionalFiles = [],
+ }
+ ]
+ }
+ );
+ }
}
diff --git a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs
index 6b551773082..c0f90ad89f4 100644
--- a/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs
+++ b/nuget/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs
@@ -101,7 +101,7 @@ public static async Task> DiscoverWithBin
{
// the built-in target `GenerateBuildDependencyFile` forces resolution of all NuGet packages, but doesn't invoke a full build
var dependencyDiscoveryTargetsPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, "DependencyDiscovery.targets");
- var args = new string[]
+ var args = new List()
{
"build",
startingProjectPath,
@@ -112,6 +112,16 @@ public static async Task> DiscoverWithBin
$"/bl:{binLogPath}"
};
var (exitCode, stdOut, stdErr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(args, startingProjectDirectory, experimentsManager);
+ if (exitCode != 0 && stdOut.Contains("error : Object reference not set to an instance of an object."))
+ {
+ // https://github.com/NuGet/Home/issues/11761#issuecomment-1105218996
+ // Due to a bug in NuGet, there can be a null reference exception thrown and adding this command line argument will work around it,
+ // but this argument can't always be added; it can cause problems in other instances, so we're taking the approach of not using it
+ // unless we have to.
+ args.Add("/RestoreProperty:__Unused__=__Unused__");
+ (exitCode, stdOut, stdErr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(args, startingProjectDirectory, experimentsManager);
+ }
+
return (exitCode, stdOut, stdErr);
}, logger, retainMSBuildSdks: true);
MSBuildHelper.ThrowOnError(stdOut);