{"record":{"id":"e2171a879b24a3ce","repo":"SubtitleEdit/subtitleedit","slug":"chatterbox-tts-synthesis-failed-int-response-st","errorCode":null,"errorMessage":"Chatterbox TTS synthesis failed ({(int)response.StatusCode}): {errorBody}","messagePattern":"Chatterbox TTS synthesis failed \\((.+?)\\): (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/ui/Features/Video/TextToSpeech/Engines/ChatterboxTtsCpp.cs","lineNumber":436,"sourceCode":"                var serverLog = SnapshotServerLog();\n                var launchCommand = _serverLaunchCommand;\n                var errMsg = $\"Chatterbox TTS server error {(int)response.StatusCode} {response.StatusCode} - \"\n                    + $\"Voice: {chatterboxVoice}, Text: {text}, RequestJson: {body}, \"\n                    + $\"ResponseBody: {errorBody}, ServerLog: {serverLog}\"\n                    + LaunchCmdSuffix(launchCommand);\n                Se.LogError(errMsg);\n                Se.WriteToolsLog(errMsg);\n\n                // The HTTP body only ever says \"backend returned empty audio\" - the reason the\n                // backend produced none is in the server log, so name it (#13508).\n                var prefix = LooksLikeCloneReferenceRejected(serverLog)\n                    ? $\"Chatterbox TTS could not use the reference voice \\\"{Path.GetFileName(chatterboxVoice.FilePath)}\\\" for cloning: \"\n                      + $\"CrispASR needs a {CloneReferenceSampleRate / 1000} kHz mono WAV and re-encoding this one did not produce that. \"\n                      + \"Re-import the voice, or convert it yourself with \"\n                      + $\"`ffmpeg -i <input> -ar {CloneReferenceSampleRate} -ac 1 -c:a pcm_s16le <output>.wav`. \"\n                    : string.Empty;\n\n                throw new InvalidOperationException(\n                    prefix\n                    + $\"Chatterbox TTS synthesis failed ({(int)response.StatusCode}): {errorBody}\"\n                    + (string.IsNullOrEmpty(serverLog) ? string.Empty : $\"{Environment.NewLine}Server log:{Environment.NewLine}{serverLog}\")\n                    + LaunchCmdSuffix(launchCommand));\n            }\n\n            await using var fileStream = File.Create(outputFileName);\n            await using var contentStream = await response.Content.ReadAsStreamAsync(cancellationToken);\n            await contentStream.CopyToAsync(fileStream, cancellationToken);\n        }\n\n        return new TtsResult(outputFileName, text);\n    }\n\n    /// <summary>\n    /// Builds the <c>/v1/audio/speech</c> JSON payload. Extracted so the cloning attestations are\n    /// unit-testable without a running crispasr server.\n    /// </summary>","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Features/Video/TextToSpeech/Engines/ChatterboxTtsCpp.cs#L418-L454","documentation":"HTTP non-success from /v1/audio/speech with LooksLikeCloneReferenceRejected false — generic backend failure. The body and the captured serverLog are appended so the real cause is visible. This is the fallback prefix path of the same throw as 193.","triggerScenarios":"crispasr returns non-2xx for any reason other than reference rejection: voice file missing from the working directory, model not loaded, malformed request body, internal 500.","commonSituations":"Voice file not present in the voices folder (server resolves `voice` relative to its cwd); model failed to load but the endpoint still answered 500; request audio/text empty; version skew between client and server.","solutions":["Inspect errorBody and the appended serverLog in the message.","Confirm the voice file exists in GetSetVoicesFolder() (the server looks it up relative to cwd).","Confirm the model is actually loaded (check tools log for startup errors).","Retry after restarting the server."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (!File.Exists(Path.Combine(GetSetVoicesFolder(), Path.GetFileName(chatterboxVoice.FilePath))))\n    return Invalid(\"voice file not present in voices folder\");","typeGuard":null,"tryCatchPattern":"try { await chatterbox.Speak(...); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Chatterbox TTS synthesis failed\"))\n{ /* inspect errorBody + serverLog; verify voice file + model load */ }","preventionTips":["Confirm the voice file is in the voices folder (server resolves it relative to cwd).","Verify the model loaded at server startup from the tools log.","Surface the serverLog alongside the HTTP body so the real cause is visible."],"tags":["chatterbox","crispasr","http","text-to-speech"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}