SubtitleEdit/subtitleedit · error · InvalidOperationException
Failed to start kokoro-tts-server
Error message
Failed to start kokoro-tts-server
What it means
InvalidOperationException from KokoroTtsCpp.EnsureServerRunningAsync when `Process.Start(psi)` returns null. As with the other engines, modern .NET throws on spawn failure rather than returning null, so this is a defensive guard that is rarely hit in practice. If reached, the OS declined to spawn the configured kokoro-tts-server with the built argument list without a thrown exception.
Source
Thrown at src/ui/Features/Video/TextToSpeech/Engines/KokoroTtsCpp.cs:331
// (relative path baked into the binary's default --vocab arg).
WorkingDirectory = GetSetFolder(),
FileName = exe,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardError = true,
RedirectStandardOutput = true,
};
psi.ArgumentList.Add("-m");
psi.ArgumentList.Add(modelPath);
psi.ArgumentList.Add("-V");
psi.ArgumentList.Add(voicesPath);
psi.ArgumentList.Add("--host");
psi.ArgumentList.Add("127.0.0.1");
psi.ArgumentList.Add("--port");
psi.ArgumentList.Add(port.ToString());
var process = Process.Start(psi)
?? throw new InvalidOperationException("Failed to start kokoro-tts-server");
Se.WriteToolsLog($"Kokoro TTS server starting - PID: {process.Id}, "
+ $"Cmd: {exe} {string.Join(' ', psi.ArgumentList)}");
var stderrBuffer = new StringBuilder();
process.ErrorDataReceived += (_, e) =>
{
if (e.Data != null) lock (stderrBuffer) stderrBuffer.AppendLine(e.Data);
};
process.OutputDataReceived += (_, e) =>
{
if (e.Data != null) lock (stderrBuffer) stderrBuffer.AppendLine(e.Data);
};
process.BeginErrorReadLine();
process.BeginOutputReadLine();
_serverProcess = process;
_serverPort = port;View on GitHub (pinned to 17a9f07487)
Solutions
- Treat as 'spawn failed for unknown reason' — verify the exe path and permissions.
- Run the exact command logged just after this throw by hand to surface the OS error.
- Confirm GetExecutableFileName() is valid and executable.
- Update the runtime if a genuine null return occurs.
Defensive patterns
Strategy: try-catch
Validate before calling
if (!File.Exists(exe)) throw new FileNotFoundException("kokoro exe missing", exe); Try / catch
try { await kokoroEngine.Speak(...); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Failed to start kokoro-tts-server"))
{
ShowLaunchCommand(ex.Message); // reproduce manually
} Prevention
- Pre-validate the exe path and permissions before Speak.
- Use the logged launch command to reproduce OS-level spawn failures.
- Keep the runtime current; a genuine null return is an upstream bug.
- Check PATH/working-directory before retrying.
When it happens
Trigger: Effectively unreachable on current .NET; the realistic failures (missing exe → FileNotFoundException; permission/path issues → Win32Exception) throw before this line.
Common situations: Observed only on runtimes/shims returning null; otherwise a dead branch.
Related errors
- Failed to start crispasr (cosyvoice3-tts)
- Failed to start crispasr (f5-tts)
- Failed to start crispasr (indextts)
- Kokoro TTS synthesis failed ({(int)response.StatusCode}): {e
- Kokoro TTS server executable not found.
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/165721736734f226.
Report an issue: GitHub.