{"record":{"id":"1a5a0787d5acef74","repo":"SubtitleEdit/subtitleedit","slug":"qwen3-tts-request-failed-ex-message-serveroutpu","errorCode":null,"errorMessage":"Qwen3 TTS request failed: {ex.Message}{ServerOutput}","messagePattern":"Qwen3 TTS request failed: (.+?)(.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/ui/Features/Video/TextToSpeech/Engines/Qwen3TtsCpp.cs","lineNumber":262,"sourceCode":"        Se.WriteToolsLog($\"Qwen3 TTS: POST {ServerBaseUrl}{endpoint} (voice={qwen3Voice}, model={modelFileName}, textLen={text.Length}, instructionLen={instruction.Length})\");\n\n        HttpResponseMessage response;\n        try\n        {\n            response = string.IsNullOrEmpty(qwen3Voice.FilePath)\n                ? await SynthesizeAsync(inputText, instruction, cancellationToken)\n                : await SynthesizeWithVoiceAsync(inputText, qwen3Voice.FilePath, instruction, cancellationToken);\n        }\n        catch (Exception ex) when (ex is not OperationCanceledException)\n        {\n            // A crashed/exited server surfaces here as a bare connection error - attach whatever\n            // the server printed (model-load / synthesis failures land in its stdout/stderr).\n            var serverOutput = SnapshotServerStderr();\n            var msg = $\"Qwen3 TTS request failed: {ex.Message}\"\n                + (serverOutput.Length == 0 ? string.Empty : $\"{Environment.NewLine}Server output:{Environment.NewLine}{serverOutput}\");\n            Se.LogError(ex, msg);\n            Se.WriteToolsLog(msg);\n            throw new InvalidOperationException(msg, ex);\n        }\n\n        using (response)\n        {\n            if (!response.IsSuccessStatusCode)\n            {\n                var errorBody = await SafeReadErrorAsync(response, cancellationToken);\n                var serverOutput = SnapshotServerStderr();\n                var errMsg = $\"Qwen3 TTS server error {(int)response.StatusCode} {response.StatusCode} - \"\n                    + $\"Voice: {qwen3Voice}, Text: {text}, Body: {errorBody}\"\n                    + (serverOutput.Length == 0 ? string.Empty : $\"{Environment.NewLine}Server output:{Environment.NewLine}{serverOutput}\");\n                Se.LogError(errMsg);\n                Se.WriteToolsLog(errMsg);\n                throw new InvalidOperationException(\n                    $\"Qwen3 TTS synthesis failed ({(int)response.StatusCode}): {errorBody}\");\n            }\n\n            await using var fileStream = File.Create(outputFileName);","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Features/Video/TextToSpeech/Engines/Qwen3TtsCpp.cs#L244-L280","documentation":"Thrown by Qwen3TtsCpp.Speak when the HTTP POST to the local qwen3-tts-server (/v1/synthesize or /v1/synthesize_with_voice) raises an exception other than OperationCanceledException. The catch wraps the raw exception in an InvalidOperationException and appends the server's captured stdout/stderr so that a server crash (which surfaces as a bare connection error) is diagnosable.","triggerScenarios":"The server process exited/crashed between health-check and the request (HttpRequestException: connection refused), the loopback port was reclaimed by another process, the request body was malformed and the server reset the connection, or the HttpClient timed out while the server was loading the model mid-request.","commonSituations":"GPU/Vulkan OOM during synthesis kills the server; the user switched models so EnsureServerRunningAsync is restarting the server while a queued Speak fires; antivirus/firewall interferes with the loopback socket; the reference WAV path in qwen3Voice.FilePath is inaccessible so the multipart upload stream faults.","solutions":["Read the appended Server output in the exception message — it usually names the real cause (CUDA/Vulkan error, model-load failure, assertion).","Confirm the server is still alive: check ToolsLog for the PID line and whether a later 'exited during startup' / 'did not report healthy' followed.","Reduce model size or instruction length if the server log shows an out-of-memory error, then retry synthesis.","If the reference WAV is involved, verify qwen3Voice.FilePath exists and is readable before the call."],"exampleFix":"// before\nresponse = await SynthesizeWithVoiceAsync(inputText, qwen3Voice.FilePath, instruction, cancellationToken);\n\n// after — guard against a vanished reference file before the request\nif (!File.Exists(qwen3Voice.FilePath))\n    throw new InvalidOperationException($\"Reference voice missing: {qwen3Voice.FilePath}\");\nresponse = await SynthesizeWithVoiceAsync(inputText, qwen3Voice.FilePath, instruction, cancellationToken);","handlingStrategy":"try-catch","validationCode":"// Validate the reference voice and server liveness before the request.\nif (!string.IsNullOrEmpty(qwen3Voice.FilePath) && !File.Exists(qwen3Voice.FilePath))\n    throw new FileNotFoundException(\"Reference voice missing\", qwen3Voice.FilePath);\nif (_serverProcess is not { HasExited: false })\n    throw new InvalidOperationException(\"Qwen3 TTS server is not running.\");","typeGuard":null,"tryCatchPattern":"try\n{\n    response = string.IsNullOrEmpty(qwen3Voice.FilePath)\n        ? await SynthesizeAsync(inputText, instruction, ct)\n        : await SynthesizeWithVoiceAsync(inputText, qwen3Voice.FilePath, instruction, ct);\n}\ncatch (OperationCanceledException) { throw; }\ncatch (Exception ex)\n{\n    var serverOutput = SnapshotServerStderr();\n    throw new InvalidOperationException($\"Qwen3 TTS request failed: {ex.Message}\" +\n        (serverOutput.Length == 0 ? string.Empty : $\"{Environment.NewLine}Server output:{Environment.NewLine}{serverOutput}\"), ex);\n}","preventionTips":["Keep the server model small enough to stay alive during peak synthesis memory.","Re-check the reference WAV path exists immediately before each request.","Serialize Speak calls per engine so a server restart can't race an in-flight request."],"tags":["tts","qwen3-tts","http","server-process","csharp"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}