stride3d/stride · error · InvalidOperationException

Could not restore NuGet packages for

Error message

Could not restore NuGet packages for {packageName} {packageVersion} ({targetFramework}).{Environment.NewLine}{diagnostics}

What it means

NuGetAssemblyResolver.SetupNuGet restores the Stride runtime NuGet packages and then collects all log entries at Warning level or above into 'diagnostics'. If the restore result reports Success == false, it throws an InvalidOperationException embedding the package name, version, target framework and those diagnostics. The real cause is always inside the appended diagnostics text.

Solutions

  1. Read the diagnostics appended to the message — it names the exact restore failure (404, auth, conflict).
  2. Verify the package id and version exist on the configured feed (dotnet package search / nuget.org).
  3. Check NuGet.config feeds, credentials, and network/proxy access; run 'dotnet restore' manually to reproduce.
  4. Ensure the requested targetFramework matches a TFM the package supports.

Example fix

// before (no feed configured)
SetupNuGet("Stride.Core", "9.9.9", "net8.0");
// after: use a published version and restore offline cache
// nuget.config: <packageSources><add key="nuget.org" value="https://api.nuget.org/v3/index.json" /></packageSources>
SetupNuGet("Stride.Core", "4.2.1", "net8.0");
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check package availability before SetupNuGet
using var http = new HttpClient();
var url = $"https://api.nuget.org/v3-flatcontainer/{packageName.ToLowerInvariant()}/{packageVersion}/{packageName.ToLowerInvariant()}.nuspec";
if (!http.SendAsync(new HttpRequestMessage(HttpMethod.Head, url)).Result.IsSuccessStatusCode)
    throw new InvalidOperationException($"Package {packageName} {packageVersion} not available on the feed.");

Try / catch

try
{
    resolver.SetupNuGet(packageName, packageVersion, targetFramework);
}
catch (InvalidOperationException ex) when (ex.Message.StartsWith("Could not restore NuGet packages"))
{
    // diagnostics are embedded in ex.Message — log them verbatim for triage
    logger.Error(ex.Message);
    throw;
}

Prevention

When it happens

Trigger: Calling SetupNuGet when the NuGet restore of packageName/packageVersion for targetFramework fails: unreachable feed, 404 for that package/version, authentication failure on a private feed, or inconsistent dependency graph.

Common situations: Wrong or nonexistent Stride package version pinned; offline machine or corporate proxy blocking nuget.org; missing NuGet.config / private feed credentials; target framework not supported by the package.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/7f894fc2d05ad589. Report an issue: GitHub.

Appendix: source

Thrown at sources/shared/Stride.NuGetResolver/NuGetAssemblyResolver.cs:138

                    {
                        // Since we execute restore synchronously, we don't want any surprise concerning synchronization context (i.e. Avalonia one doesn't work with this)
                        SynchronizationContext.SetSynchronizationContext(null);

                        foreach (var (targetFramework, packageName, packageVersion) in packagesConfigs)
                        {
                            // Parse current TFM
                            var nugetFramework = NuGetFramework.Parse(targetFramework);

                            // Only allow this specific version
                            var versionRange = new VersionRange(new NuGetVersion(packageVersion), true, new NuGetVersion(packageVersion), true);
                            var (request, result) = RestoreHelper.Restore(logger, nugetFramework, RuntimeInformation.RuntimeIdentifier, packageName, versionRange);
                            if (!result.Success)
                            {
                                var diagnostics = string.Join(Environment.NewLine,
                                    logger.Logs
                                        .Where(l => l.Level >= LogLevel.Warning)
                                        .Select(l => $"  [{l.Level}] {l.Message}"));
                                throw new InvalidOperationException(
                                    $"Could not restore NuGet packages for {packageName} {packageVersion} ({targetFramework}).{Environment.NewLine}{diagnostics}");
                            }

                            // Deployed path: pick the selected API's subfolder per package (null -> platform default).
                            var assemblies = RestoreHelper.ListAssemblies(result.LockFile, selectedGraphicsApi);

                            // Create a dictionary by assembly name
                            // note: we ignore case as filename might not be properly matching assembly name casing
                            assemblyNameToPath ??= new(StringComparer.OrdinalIgnoreCase);
                            foreach (var assembly in assemblies)
                            {
                                var extension = Path.GetExtension(assembly).ToLowerInvariant();
                                if (extension != ".dll")
                                    continue;
                                var assemblyName = Path.GetFileNameWithoutExtension(assembly);
                                // Ignore duplicates (however, make sure it's the same version otherwise display a warning)
                                if (assemblyNameToPath.TryGetValue(assemblyName, out var otherAssembly))
                                {

View on GitHub (pinned to 96fad776d2)