SubtitleEdit/subtitleedit · error · ForcedAlignerException

The forced aligner ran out of memory on this window. Try a s

Error message

The forced aligner ran out of memory on this window. Try a shorter window length.

What it means

Thrown by CrispAsrAlignOnlyRunner when the crispasr forced-aligner process exited non-zero (or produced no output) and its stderr contained 'failed to allocate'. The aligner allocates encoder activations up front, so an over-long audio window blows up memory rather than degrading — the message tells the user to shorten the window.

Source

Thrown at src/ui/Features/Files/ImportPlainText/CrispAsrAlignOnlyRunner.cs:95

        {
            await process.WaitForExitAsync(cancellationToken).ConfigureAwait(false);
        }
        catch (OperationCanceledException)
        {
            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);
            }
        }

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Reduce the window length so each call to AlignAsync gets a shorter clip (the caller chunks via FfmpegWindowAudioSource).
  2. Free memory / increase container RAM / swap before retrying.
  3. If the aligner supports a smaller batch or precision flag, set it; otherwise shorten windows further.

Example fix

// before: one huge window
await source.ExtractWindowAsync(0, totalSeconds, ct);
// after: shorter windows
const int windowSec = 600;
for (double s = 0; s < totalSeconds; s += windowSec)
    await source.ExtractWindowAsync(s, Math.Min(windowSec, totalSeconds - s), ct);
Defensive patterns

Strategy: fallback

Validate before calling

// Cap window length based on available memory
long avail = GC.GetGCMemoryInfo().TotalAvailableMemoryBytes;
var maxWindowSec = avail > 4L * 1024 * 1024 * 1024 ? 1800 : 600;
durationSeconds = Math.Min(durationSeconds, maxWindowSec);

Type guard

null

Try / catch

try { return await runner.AlignAsync(audio, text, ct); }
catch (ForcedAlignerException ex) when (ex.Message.Contains("out of memory")) {
    // shrink and retry
    return await runner.AlignAsync(audio, text, ct, windowFactor: 0.5);
}

Prevention

When it happens

Trigger: process.ExitCode != 0 || output file missing, AND stdErr.ToString().Trim() contains 'failed to allocate' (case-insensitive) inside AlignAsync.

Common situations: Feeding a long un-chunked audio file to the aligner on a memory-constrained machine or container; windowing logic that produced too-large segments; running on a GPU with insufficient VRAM.

Related errors


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