{"record":{"id":"489886a4f69efa1f","repo":"stride3d/stride","slug":"could-not-find-a-msbuild-installation-expected-16-0-or-later","errorCode":null,"errorMessage":"Could not find a MSBuild installation (expected 16.0 or later) Please ensure you have the .NET {NetMajorVersion} SDK installed from Microsoft's website","messagePattern":"Could not find a MSBuild installation \\(expected 16\\.0 or later\\) Please ensure you have the \\.NET (.+?) SDK installed from Microsoft's website","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/assets/Stride.Core.Assets/PackageSessionPublicHelper.cs","lineNumber":47,"sourceCode":"    private static VisualStudioInstance? MSBuildInstance;\n\n    /// <summary>\n    /// This method finds a compatible version of MSBuild.\n    /// </summary>\n    public static void FindAndSetMSBuildVersion()\n    {\n        // Note: this should be called only once\n        if (MSBuildInstance == null && Interlocked.Increment(ref MSBuildLocatorCount) == 1)\n        {\n            // Detect either .NET Core SDK or Visual Studio depending on current runtime\n            var isNETCore = !RuntimeInformation.FrameworkDescription.StartsWith(\".NET Framework\", StringComparison.Ordinal);\n            MSBuildInstance = MSBuildLocator.QueryVisualStudioInstances().FirstOrDefault(x => isNETCore\n                ? x.DiscoveryType == DiscoveryType.DotNetSdk && x.Version.Major == NetMajorVersion\n                : (x.DiscoveryType == DiscoveryType.VisualStudioSetup || x.DiscoveryType == DiscoveryType.DeveloperConsole) && x.Version.Major >= 16);\n\n            if (MSBuildInstance == null)\n            {\n                throw new InvalidOperationException(\"Could not find a MSBuild installation (expected 16.0 or later) \" +\n                    $\"Please ensure you have the .NET {NetMajorVersion} SDK installed from Microsoft's website\");\n            }\n\n            // Make sure it is not already loaded (otherwise MSBuildLocator.RegisterDefaults() throws an exception)\n            if (!AppDomain.CurrentDomain.GetAssemblies().Any(IsMSBuildAssembly))\n            {\n                // We can't use directly RegisterInstance because we want to avoid NuGet verison conflicts (between MSBuild/dotnet one and ours).\n                // More details at https://github.com/microsoft/MSBuildLocator/issues/127\n                // This code should be equivalent to MSBuildLocator.RegisterInstance(MSBuildInstance);\n                //  except that we load everything in another context.\n\n                ApplyDotNetSdkEnvironmentVariables(MSBuildInstance.MSBuildPath);\n\n                var msbuildAssemblyLoadContext = new AssemblyLoadContext(\"MSBuild\");\n\n                // Fall back to the SDK directory for MSBuild assemblies. Runs after the NuGet resolver\n                // (registered earlier) so Stride's pinned versions win over name-colliding SDK copies.\n                AppDomain.CurrentDomain.AssemblyResolve += (_, resolveArgs) =>","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/assets/Stride.Core.Assets/PackageSessionPublicHelper.cs#L29-L65","documentation":"Thrown by FindAndSetMSBuildVersion when no suitable MSBuild installation can be located: for .NET Core it requires a DotNetSdk discovery whose major version matches NetMajorVersion; otherwise a VS 2019 (16.0+) setup or developer console install. The method must find MSBuild before the session can build projects.","triggerScenarios":"Calling FindAndSetMSBuildVersion on a machine without the required .NET SDK version installed, or with only an older VS (pre-16.0) installation, or where MSBuildLocator cannot discover instances.","commonSituations":"CI/build agent without the .NET SDK; developer machine with only VS 2017; multiple .NET SDKs installed but none matching NetMajorVersion; SDK dotnet root not discoverable via PATH/DOTNET_ROOT.","solutions":["Install the .NET SDK matching NetMajorVersion from Microsoft's website.","Install Visual Studio 2019 or later with the .NET desktop development workload for VS-based discovery.","Verify with 'dotnet --list-sdks' that the required major version is present and on PATH.","Set DOTNET_ROOT/PATH so MSBuildLocator can discover the SDK.","If a specific minor version matters, ensure it is installed rather than only a newer major."],"exampleFix":"# before — no matching SDK\n$ dotnet --list-sdks\n3.1.426\n# after — install the required SDK major version\n$ dotnet --list-sdks\n6.0.417\n8.0.100","handlingStrategy":"fallback","validationCode":"var instances = MSBuildLocator.QueryVisualStudioInstances().ToList();\nbool hasRequired = instances.Any(i =>\n    (i.DiscoveryType == DiscoveryType.DotNetSdk && i.Version.Major == netMajor) ||\n    ((i.DiscoveryType == DiscoveryType.VisualStudioSetup || i.DiscoveryType == DiscoveryType.DeveloperConsole) && i.Version.Major >= 16));\nif (!hasRequired) throw new InvalidOperationException($\"Install .NET {netMajor} SDK or VS2019+.\");","typeGuard":null,"tryCatchPattern":"try { PackageSessionPublicHelper.FindAndSetMSBuildVersion(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"MSBuild installation\"))\n{\n    // show install instructions / download link to the user\n}","preventionTips":["Verify the required .NET SDK is installed at app startup.","Check 'dotnet --list-sdks' in setup docs/scripts.","On CI, use images with the .NET SDK preinstalled.","Call FindAndSetMSBuildVersion early with a clear error message."],"tags":["msbuild","dotnet","environment","build"],"backgroundTag":"missing-dependency","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}