NuGet.VisualStudio.Client throws NullReferenceException for projects without an assets file, preventing other VS extensions from adding their own nodes.
#14.758 aperta il 12 feb 2026
Metriche repository
- Star
- (1459 stelle)
- Metriche merge PR
- (Merge medio 464g 23h) (1 PR mergiata in 30 g)
Descrizione
NuGet Product Used
Visual Studio Package Management UI
Product Version
Visual Studio 18.2.0
Worked before?
Has not worked previously.
Impact
Other
Repro Steps & Context
Ours is a custom project system based on CPS and we use the IRelation and IRelatableItem mechanism to inject custom nodes beneath specific kinds of project nodes in Solution Explorer. We see that when the NuGet client's AssetsFileTopLevelDependenciesCollectionSourceProvider does not find an assets file for the project, it still continues to return an attached collection source, but that source returns null items. That causes an NRE in AggregateCollection.AddSourceCollection, which prevents our sources from being able to supply our custom nodes on the project.
The following code "fixes" the issue for us, though it is clearly a hack given that we have to call an async method in a sync method. At the bottom of TryCreateCollectionSource within AssetsFileTopLevelDependenciesCollectionSourceProvider, the following code skips returning a source if there is no assets file:
// *** BEGIN HACK ***
// Only return a source if we can verify the project has an assets file
// that might contain relevant data. Otherwise, we risk returning a source
// with null Items, which causes NullReferenceException in AggregateCollection.AddSourceCollection.
var configuredProject = unconfiguredProject.Services.ActiveConfiguredProjectProvider?.ActiveConfiguredProject;
if (configuredProject != null)
{
var properties = configuredProject.Services.ProjectPropertiesProvider?.GetCommonProperties();
#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits
var assetsFile = properties?.GetEvaluatedPropertyValueAsync("ProjectAssetsFile").GetAwaiter().GetResult();
#pragma warning restore VSTHRD002 // Avoid problematic synchronous waits
if (string.IsNullOrEmpty(assetsFile) || !File.Exists(assetsFile))
{
containsCollectionSource = null;
return false;
}
}
// *** END HACK ***
containsCollectionSource = collectionSource;
return true;
Verbose Logs