SubtitleEdit/subtitleedit · error · InvalidOperationException

F5-TTS (CrispASR) — the crispasr server crashed during synth

Error message

F5-TTS (CrispASR) — the crispasr server crashed during synthesis.

What it means

InvalidOperationException from F5TtsCrispAsr.Speak's HttpRequestException catch: the POST to /v1/audio/speech failed AND _serverProcess.HasExited is true, so the failure is read as the crispasr (f5-tts) server crashing mid-synthesis. The original HttpRequestException is chained and the server log is appended.

Source

Thrown at src/ui/Features/Video/TextToSpeech/Engines/F5TtsCrispAsr.cs:424

            response = await HttpClient.PostAsync($"{ServerBaseUrl}/v1/audio/speech", content, cancellationToken);
        }
        catch (HttpRequestException ex)
        {
            var serverLog = SnapshotServerLog();
            var launchCommand = _serverLaunchCommand;
            var died = _serverProcess?.HasExited == true;
            if (died)
            {
                StopServerInternal();
            }

            var failMsg = $"F5-TTS (CrispASR) request failed — Voice: {f5Voice}, Text: {text}, "
                + $"RequestJson: {body}, ServerExited: {died}, ServerLog: {serverLog}"
                + LaunchCmdSuffix(launchCommand);
            Se.LogError(ex, failMsg);
            Se.WriteToolsLog(failMsg);

            throw new InvalidOperationException(
                (died
                    ? "F5-TTS (CrispASR) — the crispasr server crashed during synthesis."
                    : "F5-TTS (CrispASR) request failed — the connection to the crispasr server was dropped.")
                + (string.IsNullOrEmpty(serverLog) ? string.Empty : $"{Environment.NewLine}Server log:{Environment.NewLine}{serverLog}")
                + LaunchCmdSuffix(launchCommand),
                ex);
        }

        using (response)
        {
            if (!response.IsSuccessStatusCode)
            {
                var errorBody = await SafeReadErrorAsync(response, cancellationToken);
                var serverLog = SnapshotServerLog();
                var launchCommand = _serverLaunchCommand;
                var errMsg = $"F5-TTS (CrispASR) server error {(int)response.StatusCode} {response.StatusCode} — "
                    + $"Voice: {f5Voice}, Text: {text}, RequestJson: {body}, "
                    + $"ResponseBody: {errorBody}, ServerLog: {serverLog}"

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Inspect the appended 'Server log' for the fatal backend error (assert/OOM).
  2. Retry with a shorter input or a different reference WAV to rule out input-triggered crashes.
  3. Re-download the F5-TTS talker model in case of corruption (IsValidLocalModelFile).
  4. Track the upstream CrispASR fix for the asserted backend and re-download when released.
Defensive patterns

Strategy: retry

Validate before calling

if (f5TtsEngine is F5TtsCrispAsr f5 && !f5.IsServerAlive()) {
    f5.StopServer(); // force clean relaunch on next Speak
}

Try / catch

try { await f5TtsEngine.Speak(text, out, voice, lang, region, model, ct); }
catch (InvalidOperationException ex) when (ex.Message.Contains("server crashed during synthesis", StringComparison.Ordinal))
{
    Se.WriteToolsLog("F5-TTS server crashed mid-synth; retrying once after relaunch.", true);
    F5TtsCrispAsr.StopServer();
    await f5TtsEngine.Speak(text, out, voice, lang, region, model, ct);
}

Prevention

When it happens

Trigger: HttpClient.PostAsync raises HttpRequestException; the catch finds _serverProcess?.HasExited == true → the 'crashed during synthesis' branch; StopServerInternal reaps the dead process.

Common situations: Synthesis OOM killing the server; a reference WAV/ref-text combo that crashes the f5-tts backend on a particular input; an upstream assert that exits the process mid-response.

Related errors


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