{"record":{"id":"6c4b7aeb3b13b746","repo":"SubtitleEdit/subtitleedit","slug":"failed-to-start-qwen3-tts-server","errorCode":null,"errorMessage":"Failed to start qwen3-tts-server","messagePattern":"Failed to start qwen3-tts-server","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/ui/Features/Video/TextToSpeech/Engines/Qwen3TtsCpp.cs","lineNumber":386,"sourceCode":"            psi.ArgumentList.Add(\"--port\");\n            psi.ArgumentList.Add(port.ToString());\n\n            if (OperatingSystem.IsWindows())\n            {\n                var vulkanPath = Se.Settings.Video.TextToSpeech.Qwen3TtsCppVulkanPath;\n                if (string.IsNullOrEmpty(vulkanPath))\n                {\n                    vulkanPath = Logic.VulkanHelper.TryFindBinFolder();\n                }\n                if (!string.IsNullOrEmpty(vulkanPath) && psi.EnvironmentVariables[\"Path\"] != null)\n                {\n                    psi.EnvironmentVariables[\"Path\"] =\n                        psi.EnvironmentVariables[\"Path\"]?.TrimEnd(';') + \";\" + vulkanPath;\n                }\n            }\n\n            var process = Process.Start(psi)\n                ?? throw new InvalidOperationException(\"Failed to start qwen3-tts-server\");\n\n            Se.WriteToolsLog($\"Qwen3 TTS server starting - PID: {process.Id}, \"\n                + $\"Cmd: {exe} {string.Join(' ', psi.ArgumentList)}\");\n\n            var stderrBuffer = new StringBuilder();\n            process.ErrorDataReceived += (_, e) =>\n            {\n                if (e.Data != null) lock (stderrBuffer) stderrBuffer.AppendLine(e.Data);\n            };\n            process.OutputDataReceived += (_, e) =>\n            {\n                if (e.Data != null) lock (stderrBuffer) stderrBuffer.AppendLine(e.Data);\n            };\n            process.BeginErrorReadLine();\n            process.BeginOutputReadLine();\n\n            _serverProcess = process;\n            _serverPort = port;","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Features/Video/TextToSpeech/Engines/Qwen3TtsCpp.cs#L368-L404","documentation":"Defensive throw after Process.Start(psi) returns null. On .NET the managed Process.Start only returns null when UseShellExecute is true and no process was launched; here UseShellExecute is false, so this branch is effectively unreachable in normal operation — it guards against a runtime/platform where Start unexpectedly yields null instead of throwing.","triggerScenarios":"A future change sets UseShellExecute=true; running under a host/runtime that returns null from Start for an empty argument list; extremely rare runtime quirk where the spawn succeeds enough to return non-throwing but no Process object is produced.","commonSituations":"Code regression that flips UseShellExecute to true; an exotic container/jail environment where process creation is partially virtualised; effectively never seen in normal desktop use.","solutions":["Confirm UseShellExecute is false (it is, in the current code) — if a fork changed it, revert.","Run the same ProcessStartInfo from a standalone harness to see whether Start returns null or throws a real Win32Exception.","If reproducible only in a sandbox, relax the sandbox's process-creation restrictions.","Treat as a code defect if hit on a normal desktop: file a bug, since Start should throw rather than return null here."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (psi.UseShellExecute)\n    throw new InvalidOperationException(\"UseShellExecute must be false for reliable Start.\");\nif (string.IsNullOrWhiteSpace(psi.FileName))\n    throw new InvalidOperationException(\"Executable path is empty.\");","typeGuard":null,"tryCatchPattern":"try { var process = Process.Start(psi) ?? throw new InvalidOperationException(\"Failed to start qwen3-tts-server\"); }\ncatch (System.ComponentModel.Win32Exception ex) { Se.LogError(ex, \"Process.Start failed\"); throw; }","preventionTips":["Keep UseShellExecute=false on all server launches.","Log the full ProcessStartInfo (FileName + ArgumentList) before Start so failures are reproducible.","Treat a null return as a defect — investigate the runtime/sandbox, don't swallow it."],"tags":["tts","qwen3-tts","process-start","defensive","csharp"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}