SubtitleEdit/subtitleedit · error · InvalidOperationException

kokoro-tts-server exited during startup (code {NativeExitCod

Error message

kokoro-tts-server exited during startup (code {NativeExitCodeHelper.Describe(process.ExitCode)}). {hint} Output: {tail}

What it means

InvalidOperationException from KokoroTtsCpp.EnsureServerRunningAsync when the kokoro-tts-server process exits before the first successful health probe. Distinctively, this one decodes the native exit code via NativeExitCodeHelper: an empty log + a 0xC00000xx code means the Windows loader killed the process before main (missing DLL, bad arch), and a human hint is appended. The described code and the last stderr tail are included.

Source

Thrown at src/ui/Features/Video/TextToSpeech/Engines/KokoroTtsCpp.cs:364

            process.BeginOutputReadLine();

            _serverProcess = process;
            _serverPort = port;
            HookProcessExitOnce();

            var deadline = DateTime.UtcNow.AddSeconds(60);
            while (DateTime.UtcNow < deadline)
            {
                ct.ThrowIfCancellationRequested();
                if (process.HasExited)
                {
                    var tail = SnapshotStderr(stderrBuffer);
                    _serverProcess = null;
                    _serverPort = 0;
                    // An empty tail plus a 0xC00000xx code means the loader killed it before main -
                    // NativeExitCodeHelper explains those instead of just printing the raw number.
                    var hint = NativeExitCodeHelper.GetHint(process.ExitCode, "Kokoro TTS", GetSetFolder());
                    throw new InvalidOperationException(
                        $"kokoro-tts-server exited during startup (code {NativeExitCodeHelper.Describe(process.ExitCode)})."
                        + (hint == null ? string.Empty : " " + hint)
                        + $" Output: {tail}");
                }
                if (await ProbeHealthAsync(port, TimeSpan.FromSeconds(1), ct))
                {
                    return;
                }
                await Task.Delay(TimeSpan.FromMilliseconds(500), ct);
            }

            var lastOutput = SnapshotStderr(stderrBuffer);
            StopServerInternal();
            throw new TimeoutException(
                $"kokoro-tts-server did not report healthy within 60s. Last output: {lastOutput}");
        }
        finally
        {

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Read the hint from NativeExitCodeHelper — a 0xC0000135 means install the VC++ redistributable / required runtime.
  2. Read the `Output:` tail for the server's own startup error (e.g. `cannot find model`, `failed to open vocab`).
  3. Confirm the `-m` modelPath and `-V` voicesPath files exist and match the binary's expected format.
  4. Ensure the working directory (GetSetFolder) contains dict/vocab.txt the binary references.
  5. Install the matching architecture (x64) build of kokoro-tts-server.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: VC++ runtime present + assets in place
if (!HasVcRedist()) PromptInstallVcRedist();
if (!File.Exists(modelPath) || !File.Exists(voicesPath)) { PromptDownloadKokoroModels(); return; }

Try / catch

try { await kokoroEngine.Speak(...); }
catch (InvalidOperationException ex) when (ex.Message.Contains("exited during startup"))
{
    // NativeExitCodeHelper hint explains loader kills (0xC0000135 etc.)
    ShowDiagnostics(ex.Message); // includes hint + Output tail
}

Prevention

When it happens

Trigger: Missing the Visual C++ runtime / required DLL (loader kills before main → 0xC0000135); running a 64-bit binary on a 32-bit OS or vice versa; model/voices path arguments invalid so the server exits immediately; the working directory (GetSetFolder) lacks the relative dict/vocab.txt the binary expects.

Common situations: Fresh Windows machine missing the VC++ redistributable; copied the binary without its dependency DLLs; wrong-architecture build downloaded; models folder moved so the `-m`/`-V` paths are wrong.

Related errors


AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13). Data as JSON: /api/errors/1adc079c7a511977. Report an issue: GitHub.