{"record":{"id":"7daed3423347a147","repo":"SubtitleEdit/subtitleedit","slug":"qwen3-tts-crispasr-the-crispasr-server-crashed","errorCode":null,"errorMessage":"Qwen3 TTS (CrispASR) — the crispasr server crashed during synthesis. | Qwen3 TTS (CrispASR) request failed — the connection to the crispasr server was dropped.{Environment.NewLine}Server log:{Environment.NewLine}{serverLog}{LaunchCmdSuffix}","messagePattern":"Qwen3 TTS \\(CrispASR\\) — the crispasr server crashed during synthesis\\. \\| Qwen3 TTS \\(CrispASR\\) request failed — the connection to the crispasr server was dropped\\.(.+?)Server log:(.+?)(.+?)(.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/ui/Features/Video/TextToSpeech/Engines/Qwen3TtsCrispAsr.cs","lineNumber":846,"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 = $\"Qwen3 TTS (CrispASR) request failed — Voice: {qwen3Voice}, 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                    ? \"Qwen3 TTS (CrispASR) — the crispasr server crashed during synthesis.\"\n                    : \"Qwen3 TTS (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 = $\"Qwen3 TTS (CrispASR) server error {(int)response.StatusCode} {response.StatusCode} — \"\n                    + $\"Voice: {qwen3Voice}, Text: {text}, RequestJson: {body}, \"\n                    + $\"ResponseBody: {errorBody}, ServerLog: {serverLog}\"","sourceCodeStart":828,"sourceCodeEnd":864,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Features/Video/TextToSpeech/Engines/Qwen3TtsCrispAsr.cs#L828-L864","documentation":"InvalidOperationException thrown when HttpClient.PostAsync to /v1/audio/speech raises an HttpRequestException. The message branches on whether _serverProcess.HasExited: if the server died it says 'crashed during synthesis', otherwise 'connection was dropped'. The captured server log and the launch command are appended, and the original HttpRequestException is chained as InnerException.","triggerScenarios":"Server OOM/abort mid-synthesis (HasExited=true); loopback socket reset; the server is overloaded and drops the keep-alive; the request payload referenced a voice whose file was deleted out from under the server.","commonSituations":"Long text causes the server to exceed GPU memory and abort; another Speak on a different thread raced the server restart; antivirus terminates the server child process; the reference voice file was removed after server start.","solutions":["Use the crashed-vs-dropped branch in the message to narrow cause: 'crashed' means inspect the server log for the abort reason; 'dropped' means network/socket.","Shorten the input text or switch to a smaller quant to reduce peak memory.","Ensure no other code path stops/restarts the crispasr server while a synthesis is in flight.","Re-import the reference voice if the server log complains it can't read the WAV."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (_serverProcess is not { HasExited: false })\n    throw new InvalidOperationException(\"crispasr server is not running.\");","typeGuard":null,"tryCatchPattern":"try { response = await HttpClient.PostAsync($\"{ServerBaseUrl}/v1/audio/speech\", content, ct); }\ncatch (HttpRequestException ex)\n{\n    var died = _serverProcess?.HasExited == true;\n    throw new InvalidOperationException(died ? \"crispasr crashed during synthesis\" : \"connection dropped\", ex);\n}","preventionTips":["Serialize Speak calls so a restart can't race an in-flight request.","Cap input length to keep peak memory within the server's budget.","Watch _serverProcess.HasExited and refuse to send when dead."],"tags":["tts","crispasr","http","server-process","csharp"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}