SubtitleEdit/subtitleedit · error · ForcedAlignerException
The forced aligner failed (exit code {process.ExitCode}).
Error message
The forced aligner failed (exit code {process.ExitCode}). What it means
The generic catch-all from CrispAsrAlignOnlyRunner.AlignAsync: the aligner exited non-zero (or wrote no .aligned.srt) and the stderr did not match the out-of-memory signature, so the runner wraps the exit code plus captured stderr into a ForcedAlignerException.
Source
Thrown at src/ui/Features/Files/ImportPlainText/CrispAsrAlignOnlyRunner.cs:99
{
TryKill(process);
throw;
}
if (process.ExitCode != 0 || !File.Exists(outputFileName))
{
var detail = stdErr.ToString().Trim();
_log?.Invoke(detail);
// The aligner allocates its encoder activations up front, so a window that is
// too long for the available memory fails here rather than degrading.
if (detail.Contains("failed to allocate", StringComparison.OrdinalIgnoreCase))
{
throw new ForcedAlignerException(
"The forced aligner ran out of memory on this window. Try a shorter window length.", detail);
}
throw new ForcedAlignerException($"The forced aligner failed (exit code {process.ExitCode}).", detail);
}
return await File.ReadAllTextAsync(outputFileName, cancellationToken).ConfigureAwait(false);
}
private static void TryKill(Process process)
{
try
{
if (!process.HasExited)
{
process.Kill(true);
}
}
catch
{
// Killing a process that just exited on its own is not an error.
}View on GitHub (pinned to 17a9f07487)
Solutions
- Inspect the Detail property of the ForcedAlignerException — it carries the aligner's stderr verbatim, which states the real cause.
- Confirm the -am model path exists and matches the aligner version.
- Confirm the input WAV is 16 kHz mono PCM as the aligner expects.
- Confirm the text file is non-empty and UTF-8.
- Re-run with the aligner directly to reproduce, then fix the reported error.
Example fix
// surface the detail
catch (ForcedAlignerException ex) {
logger.Error($"aligner exit {ex.Detail}");
} Defensive patterns
Strategy: try-catch
Validate before calling
// Validate model + audio before invoking
if (!File.Exists(_alignerModel)) throw new ArgException($"Aligner model not found: {_alignerModel}");
if (!File.Exists(audioFileName)) throw new ArgException($"Audio not found: {audioFileName}");
if (new FileInfo(audioFileName).Length == 0) throw new ArgException("Audio file is empty."); Type guard
null
Try / catch
try { return await runner.AlignAsync(a, t, ct); }
catch (ForcedAlignerException ex) { logger.Error($"aligner failed: {ex.Message}\ndetail: {ex.Detail}"); throw; } Prevention
- Always log ex.Detail — it carries the aligner's own error text.
- Pre-validate model path, audio existence, and sample rate.
- Reproduce failing cases by invoking the aligner directly with the same args.
When it happens
Trigger: process.ExitCode != 0 || !File.Exists(outputFileName), and the stderr detail does not contain 'failed to allocate'.
Common situations: Missing or wrong -am model path; corrupt/unreadable audio; text file length mismatch; unsupported sample rate; aligner binary crash; model/text encoding mismatch; cancelled mid-run leaving no output.
Related errors
- The forced aligner ran out of memory on this window. Try a s
- Could not cut the audio window with ffmpeg.
- CrispASR executable not found - please use the 'Download' bu
- CrispASR MADLAD model not found - please use the 'Download'
- Tesseract exited with code {proc.ExitCode}: {err}
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/f0af88d6157e03da.
Report an issue: GitHub.