SubtitleEdit/subtitleedit · error · Exception

CrispASR exited with code

Error message

CrispASR exited with code {process.ExitCode}: {Error}

What it means

Thrown after the CrispASR command-line process (madlad backend) exits with a non-zero code. The executable and model paths are validated earlier (lines 47-57), so this fires only when the process launched successfully but failed at runtime. The captured stderr is appended to the message.

Solutions

  1. Run the exact CrispASR command from the error's stderr manually in a terminal to see the native error.
  2. Verify the model file matches the CrispASR version (re-download via the Download button).
  3. Confirm the source/target language codes are valid two-letter ISO 639-1 codes supported by MADLAD-400.
  4. Install required runtime dependencies (CUDA toolkit, Visual C++ Redistributable on Windows).
  5. Shorten the input text (MaxCharacters is 1000) and retry.

Example fix

// before
Error = errorBuilder.ToString().Trim();
throw new Exception($"CrispASR exited with code {process.ExitCode}: {Error}");

// after - surface exit code distinctly and log stderr for diagnostics
Error = errorBuilder.ToString().Trim();
SeLogger.Error($"CrispASR exited with code {process.ExitCode}. Args: {startInfo.Arguments}. Stderr: {Error}");
throw new Exception($"CrispASR exited with code {process.ExitCode}: {Error}", new InvalidOperationException(Error));
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate inputs before launching the process
if (string.IsNullOrWhiteSpace(_executablePath) || !File.Exists(_executablePath))
    throw new InvalidOperationException("CrispASR executable path is invalid: " + _executablePath);
if (string.IsNullOrWhiteSpace(_modelPath) || !File.Exists(_modelPath))
    throw new InvalidOperationException("CrispASR model path is invalid: " + _modelPath);
if (string.IsNullOrWhiteSpace(sourceLanguageCode) || string.IsNullOrWhiteSpace(targetLanguageCode))
    throw new ArgumentException("Source and target language codes must be set.");
if (text.Length > MaxCharacters)
    throw new ArgumentException($"Input text ({text.Length} chars) exceeds MaxCharacters ({MaxCharacters}).");

Type guard

public static bool IsCrispAsrReady(string exePath, string modelPath) =>
    !string.IsNullOrWhiteSpace(exePath) && File.Exists(exePath) &&
    !string.IsNullOrWhiteSpace(modelPath) && File.Exists(modelPath);

Try / catch

try
{
    return await translator.Translate(text, src, tgt, token);
}
catch (Exception ex) when (ex.Message.Contains("CrispASR exited with code"))
{
    // Surface stderr to the user; offer to re-download the model or check language codes
    logger.Error(ex, "CrispASR failed: {Message}");
    throw new InvalidOperationException("CrispASR runtime failure - check the model, language codes, and dependencies.", ex);
}

Prevention

When it happens

Trigger: Translate() spawns CrispASR with args --backend madlad, a model path, the source/target language codes, and the trimmed input text; the process runs to completion but process.ExitCode != 0. Also fires when the CancellationToken triggers process.Kill() and the exit code is non-zero on some platforms.

Common situations: Missing CUDA/runtime DLLs on Windows; a corrupted or wrong-architecture model file; language codes CrispASR does not accept (it expects ISO codes the MADLAD model knows); input text exceeding the model's token budget; antivirus blocking the executable mid-run; permission denied reading the model.

Related errors


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

Appendix: source

Thrown at src/libuilogic/AutoTranslate/CrispAsrMadladTranslate.cs:131

                        {
                            process.Kill();
                        }
                    }
                    catch
                    {
                        // ignore - process may have already exited
                    }

                    exitedSource.TrySetCanceled();
                }))
                {
                    await exitedSource.Task.ConfigureAwait(false);
                }

                if (process.ExitCode != 0)
                {
                    Error = errorBuilder.ToString().Trim();
                    throw new Exception($"CrispASR exited with code {process.ExitCode}: {Error}");
                }

                return outputBuilder.ToString().Trim();
            }
        }

        private static List<TranslationPair> ListLanguages()
        {
            var result = new List<TranslationPair>();
            var seen = new HashSet<string>();
            foreach (var culture in Utilities.GetSubtitleLanguageCultures(false))
            {
                if (!string.IsNullOrEmpty(culture.TwoLetterISOLanguageName) && seen.Add(culture.TwoLetterISOLanguageName))
                {
                    result.Add(new TranslationPair(culture.EnglishName, culture.TwoLetterISOLanguageName));
                }
            }

View on GitHub (pinned to 17a9f07487)