{"record":{"id":"ee5138b376cdeda3","repo":"SubtitleEdit/subtitleedit","slug":"cosyvoice3-crispasr-request-failed-the-connect","errorCode":null,"errorMessage":"CosyVoice3 (CrispASR) request failed — the connection to the crispasr server was dropped.","messagePattern":"CosyVoice3 \\(CrispASR\\) request failed — the connection to the crispasr server was dropped\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/ui/Features/Video/TextToSpeech/Engines/CosyVoice3CrispAsr.cs","lineNumber":588,"sourceCode":"            response = await HttpClient.PostAsync($\"{ServerBaseUrl}/v1/audio/speech\", content, cancellationToken);\n        }\n        catch (HttpRequestException ex)\n        {\n            var serverLog = SnapshotServerLog();\n            var launchCommand = _serverLaunchCommand;\n            var died = _serverProcess?.HasExited == true;\n            if (died)\n            {\n                StopServerInternal();\n            }\n\n            var failMsg = $\"CosyVoice3 (CrispASR) request failed — Voice: {cosyVoice}, Text: {text}, \"\n                + $\"RequestJson: {body}, ServerExited: {died}, ServerLog: {serverLog}\"\n                + LaunchCmdSuffix(launchCommand);\n            Se.LogError(ex, failMsg);\n            Se.WriteToolsLog(failMsg);\n\n            throw new InvalidOperationException(\n                (died\n                    ? \"CosyVoice3 (CrispASR) — the crispasr server crashed during synthesis.\"\n                    : \"CosyVoice3 (CrispASR) request failed — the connection to the crispasr server was dropped.\")\n                + (string.IsNullOrEmpty(serverLog) ? string.Empty : $\"{Environment.NewLine}Server log:{Environment.NewLine}{serverLog}\")\n                + LaunchCmdSuffix(launchCommand),\n                ex);\n        }\n\n        using (response)\n        {\n            if (!response.IsSuccessStatusCode)\n            {\n                var errorBody = await SafeReadErrorAsync(response, cancellationToken);\n                var serverLog = SnapshotServerLog();\n                var launchCommand = _serverLaunchCommand;\n                var errMsg = $\"CosyVoice3 (CrispASR) server error {(int)response.StatusCode} {response.StatusCode} — \"\n                    + $\"Voice: {cosyVoice}, Text: {text}, RequestJson: {body}, \"\n                    + $\"ResponseBody: {errorBody}, ServerLog: {serverLog}\"","sourceCodeStart":570,"sourceCodeEnd":606,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Features/Video/TextToSpeech/Engines/CosyVoice3CrispAsr.cs#L570-L606","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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()."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for (int attempt = 1; attempt <= 2; attempt++)\ntry { await cosyVoice3Engine.Speak(text, out, voice, lang, region, model, ct); return; }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"connection to the crispasr server was dropped\", StringComparison.Ordinal) && attempt < 2)\n{ Se.WriteToolsLog($\"Transient CosyVoice3 connection drop, retry {attempt}.\", true); }\n// server still alive — no StopServer needed","preventionTips":["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."],"tags":["tts","cosyvoice3","crispasr","connection-drop","transient","http-request-exception"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}