stride3d/stride · error · InvalidOperationException
Failed to start .
Error message
Failed to start {CommandsPackageId} {version}. What it means
After locating and launching the version-matched Stride.VisualStudio.Commands executable, Start calls Process.Start; if the OS returns null (the process could not be launched), this InvalidOperationException is thrown. Unlike the connection loop, this failure happens before any pipe retry logic and indicates the executable itself could not be spawned.
Solutions
- Confirm the mapped executable runs standalone: execute the path printed in the error manually and fix whatever blocks it (missing .NET runtime, unblock the file, adjust antivirus).
- Install the .NET runtime matching the framework folder the Commands package restored under (net10.0/net8.0/net6.0) for your OS and architecture.
- Re-restore the package after clearing caches ('dotnet nuget locals all --clear') in case the apphost binary is corrupt.
- Check OS security policies (AppLocker/Defender/quarantine) that silently prevent spawning the tool executable.
Example fix
// before (blocked/unlaunchable apphost) C:\Users\me\.nuget\packages\stride.visualstudio.commands\4.1.0\...\Stride.VisualStudio.Commands.exe <- returns null from Process.Start // after (unblock and verify runtime) Unblock-File .\Stride.VisualStudio.Commands.exe dotnet --list-runtimes # ensure the required runtime is installed
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the mapped executable is launchable before spawning
var exe = LocateCommandsExecutable(version);
if (exe is null || !File.Exists(exe))
throw new InvalidOperationException("Commands executable missing — check the NuGet restore first.");
if (!OperatingSystem.IsWindows())
Console.Error.WriteLine("Commands host is Windows-targeted; Process.Start may fail on this OS."); Type guard
static bool CanLaunch(string path) =>
File.Exists(path) &&
(OperatingSystem.IsWindows() || !(path.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))); Try / catch
try {
using var gen = LegacyShaderCodeGenerator.Start(version);
bytes = gen.Generate(shaderFile, shaderContent);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Failed to start Stride.VisualStudio.Commands")) {
Console.Error.WriteLine($"Tool spawn failed: {ex.Message}. Check installed .NET runtimes and AV policy.");
return ExitCode.LaunchFailure;
} Prevention
- Ensure the .NET runtimes (net6.0/net8.0/net10.0 as applicable) are installed for the architecture the Commands apphost was restored for.
- Unblock downloaded package binaries and confirm antivirus/AppLocker does not block the tool's exe.
- Smoke-test the tool executable manually once per machine before relying on the CLI.
- Run 'dotnet --list-runtimes' in CI images to keep the required runtimes present.
When it happens
Trigger: Process.Start(new ProcessStartInfo(executable, "--pipe=...") { UseShellExecute = false }) returns null — typically because the mapped executable path is not a launchable process image on the current OS/architecture.
Common situations: LoaderToolLocator mapped the restored assembly to a host not runnable on this machine (wrong architecture, e.g. x86 vs arm64, or a Windows-only host); antivirus or policy blocking execution of the downloaded tool; a net6.0/net8.0/net10.0 apphost whose matching runtime is absent so the launcher refuses to start it; file marked not-executable or blocked (Zone.Identifier) after download.
Related errors
- Could not restore (needed to regenerate shader code). Check…
- Could not start install package process
- Metadata loaded from nuspec cannot have more than one group…
- Could not restore package
- Could not find installation path for package
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/1ece400fe5f4fb0f.
Report an issue: GitHub.
Appendix: source
Thrown at sources/launcher/Stride.Cli/Legacy/LegacyShaderCodeGenerator.cs:46
this.process = process;
this.client = client;
}
/// <summary>Restores the version-matched Commands, spawns it, and connects. Caller owns the returned instance.</summary>
public static LegacyShaderCodeGenerator Start(PackageVersion version)
{
var executable = LocateCommandsExecutable(version)
?? throw new InvalidOperationException($"Could not restore {CommandsPackageId} {version} (needed to regenerate shader code). Check your NuGet sources.");
var address = "Stride/StrideCliShaders/" + Guid.NewGuid();
var startInfo = new ProcessStartInfo(executable, $"--pipe=\"{address}\"")
{
UseShellExecute = false,
CreateNoWindow = true,
WorkingDirectory = Path.GetDirectoryName(executable)!,
};
var process = Process.Start(startInfo)
?? throw new InvalidOperationException($"Failed to start {CommandsPackageId} {version}.");
// Stride 4.1 spoke ServiceWire 5.3.4 (BinaryFormatter, no compression); 4.2+ uses the modern default.
var legacy = version.Version < new Version(4, 2);
// The server needs a moment to open its named pipe; retry the connection briefly.
for (var attempt = 0; ; attempt++)
{
try
{
var endpoint = new NpEndPoint(address + "/IStrideCommands");
var client = legacy
? new NpClient<IStrideCommands>(endpoint, new LegacyBinaryFormatterSerializer(), new LegacyDoNothingCompressor())
: new NpClient<IStrideCommands>(endpoint);
return new LegacyShaderCodeGenerator(process, client);
}
catch when (attempt < 30 && !process.HasExited)
{
Thread.Sleep(100);View on GitHub (pinned to 96fad776d2)