SubtitleEdit/subtitleedit · error · InvalidOperationException
CosyVoice3 (CrispASR) request failed — the connection to the
Error message
CosyVoice3 (CrispASR) request failed — the connection to the crispasr server was dropped.
What it means
InvalidOperationException from CosyVoice3CrispAsr.Speak's HttpRequestException catch: the POST failed but the server process is still alive (_serverProcess?.HasExited != true), so the request died without a server crash — a dropped/reset connection rather than a dead process. The original exception is chained and the server log is appended.
Source
Thrown at src/ui/Features/Video/TextToSpeech/Engines/CosyVoice3CrispAsr.cs:588
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 = $"CosyVoice3 (CrispASR) request failed — Voice: {cosyVoice}, Text: {text}, "
+ $"RequestJson: {body}, ServerExited: {died}, ServerLog: {serverLog}"
+ LaunchCmdSuffix(launchCommand);
Se.LogError(ex, failMsg);
Se.WriteToolsLog(failMsg);
throw new InvalidOperationException(
(died
? "CosyVoice3 (CrispASR) — the crispasr server crashed during synthesis."
: "CosyVoice3 (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 = $"CosyVoice3 (CrispASR) server error {(int)response.StatusCode} {response.StatusCode} — "
+ $"Voice: {cosyVoice}, Text: {text}, RequestJson: {body}, "
+ $"ResponseBody: {errorBody}, ServerLog: {serverLog}"View on GitHub (pinned to 17a9f07487)
Solutions
- Retry the synthesis call — EnsureServerRunningAsync will reuse or restart the healthy server.
- Reduce input text length to shorten request duration and avoid keep-alive drops.
- Check 'Server log' for transient backend errors that did not kill the process.
- If it recurs, force a server restart by changing voice/model key or calling CosyVoice3CrispAsr.StopServer().
Defensive patterns
Strategy: retry
Try / catch
for (int attempt = 1; attempt <= 2; attempt++)
try { await cosyVoice3Engine.Speak(text, out, voice, lang, region, model, ct); return; }
catch (InvalidOperationException ex) when (ex.Message.Contains("connection to the crispasr server was dropped", StringComparison.Ordinal) && attempt < 2)
{ Se.WriteToolsLog($"Transient CosyVoice3 connection drop, retry {attempt}.", true); }
// server still alive — no StopServer needed Prevention
- Keep synthesis inputs short enough to avoid keep-alive/connection drops.
- On repeated drops, force a server restart to reset connection state.
- Treat a dropped connection (server alive) as transient and retry before surfacing failure.
When it happens
Trigger: HttpClient.PostAsync raises HttpRequestException while the server process is still running; e.g. the TCP connection was reset, a keep-alive timed out, the server closed the socket mid-response, or a transient loopback issue occurred.
Common situations: Long synthesis where the server closed the idle control connection; loopback stack/network blip; the server temporarily stopped accepting connections under load; transient OS resource exhaustion.
Related errors
- F5-TTS (CrispASR) request failed — the connection to the cri
- CosyVoice3 (CrispASR) — the crispasr server crashed during s
- CosyVoice3 (CrispASR) synthesis failed ({(int)response.Statu
- CrispASR executable not found. Install CrispASR via Video →
- Failed to start crispasr (cosyvoice3-tts)
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/ee5138b376cdeda3.
Report an issue: GitHub.