{"record":{"id":"93f46a7b4dd3bf0c","repo":"SubtitleEdit/subtitleedit","slug":"crispasr-chatterbox-did-not-report-healthy-withi","errorCode":null,"errorMessage":"crispasr (chatterbox) did not report healthy within 15 minutes. Last output: {lastOutput}{LaunchCmdSuffix}","messagePattern":"crispasr \\(chatterbox\\) did not report healthy within 15 minutes\\. Last output: (.+?)(.+?)","errorType":"exception","errorClass":"TimeoutException","httpStatus":null,"severity":"error","filePath":"src/ui/Features/Video/TextToSpeech/Engines/ChatterboxTtsCpp.cs","lineNumber":686,"sourceCode":"                            + \"https://github.com/CrispStrobe/CrispASR/issues with the log below.\"\n                            + Environment.NewLine + Environment.NewLine + tail\n                            + LaunchCmdSuffix(exitedLaunchCommand));\n                    }\n                    throw new InvalidOperationException(\n                        $\"crispasr (chatterbox) exited during startup (code {exitCode}). Output: {tail}\"\n                        + LaunchCmdSuffix(exitedLaunchCommand));\n                }\n                if (await ProbeHealthAsync(port, TimeSpan.FromSeconds(2), ct))\n                {\n                    return;\n                }\n                await Task.Delay(TimeSpan.FromSeconds(1), ct);\n            }\n\n            var lastOutput = SnapshotServerLog();\n            var timeoutLaunchCommand = _serverLaunchCommand;\n            StopServerInternal();\n            throw new TimeoutException(\n                $\"crispasr (chatterbox) did not report healthy within 15 minutes. Last output: {lastOutput}\"\n                + LaunchCmdSuffix(timeoutLaunchCommand));\n        }\n        finally\n        {\n            ServerLock.Release();\n        }\n    }\n\n    private static bool LooksLikeOutdatedCrispAsr(string output)\n    {\n        // v0.5.x exits 0 and prints `error: unknown argument: ...` when it doesn't\n        // recognise --voice-dir / --backend chatterbox. v0.6.x without the chatterbox\n        // backend (e.g. ASR-only build) prints `unknown backend 'chatterbox'`.\n        return output.Contains(\"unknown argument\", StringComparison.Ordinal)\n            || output.Contains(\"unknown backend\", StringComparison.Ordinal);\n    }\n","sourceCodeStart":668,"sourceCodeEnd":704,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Features/Video/TextToSpeech/Engines/ChatterboxTtsCpp.cs#L668-L704","documentation":"TimeoutException thrown by ChatterboxTtsCpp when the 15-minute startup deadline (DateTime.UtcNow.AddMinutes(15)) elapses without a successful /health probe and without the process exiting. The deadline is intentionally long because the first run auto-downloads ~880 MB of model weights.","triggerScenarios":"EnsureServerRunningAsync launches crispasr; ProbeHealthAsync returns false every 2s for the full 15 minutes; process stays alive (so the exit-path errors never fire). On timeout, StopServerInternal kills it and throws.","commonSituations":"First run on a slow/throttled network where the ~880 MB download does not finish in 15 min; the server bound to the port but /health is hung; antivirus/proxy blocking the model CDN so download stalls silently; CPU so slow that model warm-up exceeds the window.","solutions":["Re-run — the partial model download is cached and the second attempt continues from where it stopped.","Check network/proxy/antivirus access to the CrispASR model host so the download is not throttled.","Pre-stage the GGUFs in the configured models folder so startup is local and fast.","If on a very slow CPU, allow more time or move to a GPU host for warm-up.","Inspect 'Last output' in the message — if it shows a download progress stall, the CDN/firewall is the culprit."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// First run downloads ~880 MB; the 15-min deadline can be tight. If you can detect a partial\n// download, pre-stage or resume before calling Speak so the local deadline (not the download\n// one) applies.","typeGuard":null,"tryCatchPattern":"try { await engine.Speak(text, out, voice, lang, region, model, ct); }\ncatch (TimeoutException ex) when (ex.Message.Contains(\"did not report healthy within 15 minutes\", StringComparison.Ordinal))\n{\n    Se.WriteToolsLog(\"Chatterbox startup timed out (likely download); retrying.\", true);\n    await engine.Speak(text, out, voice, lang, region, model, ct); // download is now cached\n}","preventionTips":["Pre-download the Chatterbox GGUFs out-of-band so the first synthesis is local and fast.","Whitelist the CrispASR model CDN in proxy/AV so the download is not throttled.","On slow networks, expect the first run to need a second attempt — the cache makes it fast."],"tags":["tts","chatterbox","crispasr","timeout","download","startup"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}