SubtitleEdit/subtitleedit · critical · InvalidOperationException

crispasr (qwen3-tts) exited during startup (code {exitCode})

Error message

crispasr (qwen3-tts) exited during startup (code {exitCode}). Output: {tail}{LaunchCmdSuffix}

What it means

InvalidOperationException thrown during the crispasr startup health-wait when process.HasExited becomes true before /health succeeds. The message includes the raw exit code, the captured server log tail, and the launch command suffix so the user can reproduce the failing invocation manually.

Source

Thrown at src/ui/Features/Video/TextToSpeech/Engines/Qwen3TtsCrispAsr.cs:1025

            _serverPort = port;
            _serverModelKey = modelKey;
            HookProcessExitOnce();

            // First-run auto-download (~2 GB talker + ~986 MB codec) needs a generous timeout.
            var deadline = DateTime.UtcNow.AddMinutes(hasLocalTalker && hasLocalCodec ? 5 : 30);
            while (DateTime.UtcNow < deadline)
            {
                ct.ThrowIfCancellationRequested();
                if (process.HasExited)
                {
                    var tail = SnapshotServerLog();
                    var exitCode = process.ExitCode;
                    var exitedLaunchCommand = _serverLaunchCommand;
                    _serverProcess = null;
                    _serverPort = 0;
                    _serverModelKey = null;
                    _serverLaunchCommand = null;
                    throw new InvalidOperationException(
                        $"crispasr (qwen3-tts) exited during startup (code {exitCode}). Output: {tail}"
                        + LaunchCmdSuffix(exitedLaunchCommand));
                }
                if (await ProbeHealthAsync(port, TimeSpan.FromSeconds(2), ct))
                {
                    return;
                }
                await Task.Delay(TimeSpan.FromSeconds(1), ct);
            }

            var lastOutput = SnapshotServerLog();
            var timeoutLaunchCommand = _serverLaunchCommand;
            StopServerInternal();
            throw new TimeoutException(
                $"crispasr (qwen3-tts) did not report healthy within {(hasLocalTalker && hasLocalCodec ? 5 : 30)} minutes. Last output: {lastOutput}"
                + LaunchCmdSuffix(timeoutLaunchCommand));
        }
        finally

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Read the appended Output tail — crispasr prints its fatal reason (e.g. 'failed to load talker', 'unknown backend').
  2. Run the printed Launch command manually in a terminal to see the full stderr.
  3. Confirm the talker and codec GGUFs are complete downloads or let --auto-download re-fetch.
  4. Match the --backend value to a backend that exists in this crispasr build.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: confirm model files and voice dir exist.
if (!Directory.Exists(GetSetVoicesFolder()))
    throw new DirectoryNotFoundException("--voice-dir target missing.");
if (hasLocalTalker && !IsValidLocalModelFile(talker, GetTalkerFileName(modelKey)))
    throw new FileNotFoundException("Talker model invalid", talker);

Try / catch

try { await EnsureServerRunningAsync(modelKey, ct); }
catch (InvalidOperationException ex) when (ex.Message.Contains("exited during startup"))
{ await ShowServerStartupHelpAsync(ex.Message); throw; }

Prevention

When it happens

Trigger: Missing shared libraries abort crispasr before main; the talker/codec GGUF specified via -m is missing or corrupt; the --backend name doesn't match a compiled backend; --voice-dir points at a non-existent folder and crispasr aborts; GPU/driver incompatibility.

Common situations: First run before models are staged locally (the code falls back to --auto-download, which can still fail offline); a backend was compiled out of this crispasr build; a partial model download; driver/runtime mismatch.

Related errors


AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13). Data as JSON: /api/errors/636f424fd1dc5c33. Report an issue: GitHub.