SubtitleEdit/subtitleedit · warning · InvalidOperationException
Failed to start llama-server
Error message
Failed to start llama-server
What it means
InvalidOperationException thrown when Process.Start(psi) returns null. On modern .NET Process.Start effectively never returns null (it throws Win32Exception on launch failure), so this guard is defensive and almost unreachable in practice. The earlier File.Exists(exe) check already removed the most common launch failure.
Source
Thrown at src/libuilogic/LlamaCpp/LlamaCppServerManager.cs:574
// clients' cache_prompt this keeps repeated prompt prefixes (system prompt,
// rolling context) from being re-ingested every request. Auto-disables with a
// warning on models whose context cannot shift. Not combined with multimodal -
// vision chunks cannot be shifted.
psi.ArgumentList.Add("--cache-reuse");
psi.ArgumentList.Add("256");
}
if (model.NoJinja)
{
psi.ArgumentList.Add("--no-jinja");
}
if (model.ChatTemplate != null)
{
psi.ArgumentList.Add("--chat-template");
psi.ArgumentList.Add(model.ChatTemplate);
}
var process = Process.Start(psi)
?? throw new InvalidOperationException("Failed to start llama-server");
LogAction?.Invoke($"llama-server starting - PID: {process.Id}, Cmd: {FormatLaunchCommand(exe, psi.ArgumentList)}");
lock (_serverLog)
{
_serverLog.Clear();
}
process.ErrorDataReceived += (_, e) =>
{
if (e.Data != null)
{
lock (_serverLog) _serverLog.AppendLine(e.Data);
}
};
process.OutputDataReceived += (_, e) =>
{
if (e.Data != null)View on GitHub (pinned to 17a9f07487)
Solutions
- If you actually hit this, capture psi.FileName and re-run the same command in a shell to see the real OS error (which Process.Start normally surfaces as Win32Exception).
- Verify the llama-server binary is a valid executable for the current platform (x64 vs arm64, executable bit on Linux).
- On Linux, ensure execute permission: chmod +x on the resolved exe path.
- As a last resort, update the .NET runtime — null returns were more plausible on very old framework versions.
Example fix
// before
var process = Process.Start(psi)
?? throw new InvalidOperationException("Failed to start llama-server");
// after
Process process;
try { process = Process.Start(psi) ?? throw new InvalidOperationException("Failed to start llama-server"); }
catch (Win32Exception ex) { throw new InvalidOperationException($"Failed to start llama-server ({psi.FileName}): {ex.Message}", ex); } Defensive patterns
Strategy: try-catch
Validate before calling
if (!File.Exists(exe)) return Result.Fail($"llama-server missing at {exe}");
if (Environment.OSVersion.Platform == PlatformID.Unix)
AssertUnixExecBit(exe); Type guard
null
Try / catch
Process process;
try { process = Process.Start(psi) ?? throw new InvalidOperationException("Failed to start llama-server"); }
catch (Win32Exception ex) { throw new InvalidOperationException($"Launch failed for {psi.FileName}: {ex.Message}", ex); }
catch (PlatformNotSupportedException ex) { throw new InvalidOperationException("Process launch unsupported on this platform.", ex); } Prevention
- Verify the executable is a valid binary for the OS/arch before launching.
- On Unix, chmod +x the resolved exe path during install.
- Always include the exe path in any launch-failure exception.
When it happens
Trigger: Process.Start returns null — only documented to happen when the ProcessStartInfo cannot launch a process at all (e.g. FileName is empty or a degenerate info). On .NET 6+ genuine launch failures surface as Win32Exception, not null.
Common situations: Almost never seen in the wild; if reported it is usually a framework/runtime edge case or a corrupted llama-server executable that the OS rejects at CreateProcess time.
Related errors
- BDN XML document could not be created.
- BDN XML Events node not found.
- Failed to start crispasr (cosyvoice3-tts)
- Failed to start crispasr (f5-tts)
- Failed to start crispasr (moss-tts)
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/7addfb6940426009.
Report an issue: GitHub.