{"record":{"id":"85b69e319c1f1aad","repo":"SubtitleEdit/subtitleedit","slug":"the-forced-aligner-ran-out-of-memory-on-this-windo","errorCode":null,"errorMessage":"The forced aligner ran out of memory on this window. Try a shorter window length.","messagePattern":"The forced aligner ran out of memory on this window\\. Try a shorter window length\\.","errorType":"exception","errorClass":"ForcedAlignerException","httpStatus":null,"severity":"error","filePath":"src/ui/Features/Files/ImportPlainText/CrispAsrAlignOnlyRunner.cs","lineNumber":95,"sourceCode":"        {\n            await process.WaitForExitAsync(cancellationToken).ConfigureAwait(false);\n        }\n        catch (OperationCanceledException)\n        {\n            TryKill(process);\n            throw;\n        }\n\n        if (process.ExitCode != 0 || !File.Exists(outputFileName))\n        {\n            var detail = stdErr.ToString().Trim();\n            _log?.Invoke(detail);\n\n            // The aligner allocates its encoder activations up front, so a window that is\n            // too long for the available memory fails here rather than degrading.\n            if (detail.Contains(\"failed to allocate\", StringComparison.OrdinalIgnoreCase))\n            {\n                throw new ForcedAlignerException(\n                    \"The forced aligner ran out of memory on this window. Try a shorter window length.\", detail);\n            }\n\n            throw new ForcedAlignerException($\"The forced aligner failed (exit code {process.ExitCode}).\", detail);\n        }\n\n        return await File.ReadAllTextAsync(outputFileName, cancellationToken).ConfigureAwait(false);\n    }\n\n    private static void TryKill(Process process)\n    {\n        try\n        {\n            if (!process.HasExited)\n            {\n                process.Kill(true);\n            }\n        }","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Features/Files/ImportPlainText/CrispAsrAlignOnlyRunner.cs#L77-L113","documentation":"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.","triggerScenarios":"process.ExitCode != 0 || output file missing, AND stdErr.ToString().Trim() contains 'failed to allocate' (case-insensitive) inside AlignAsync.","commonSituations":"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.","solutions":["Reduce the window length so each call to AlignAsync gets a shorter clip (the caller chunks via FfmpegWindowAudioSource).","Free memory / increase container RAM / swap before retrying.","If the aligner supports a smaller batch or precision flag, set it; otherwise shorten windows further."],"exampleFix":"// before: one huge window\nawait source.ExtractWindowAsync(0, totalSeconds, ct);\n// after: shorter windows\nconst int windowSec = 600;\nfor (double s = 0; s < totalSeconds; s += windowSec)\n    await source.ExtractWindowAsync(s, Math.Min(windowSec, totalSeconds - s), ct);","handlingStrategy":"fallback","validationCode":"// Cap window length based on available memory\nlong avail = GC.GetGCMemoryInfo().TotalAvailableMemoryBytes;\nvar maxWindowSec = avail > 4L * 1024 * 1024 * 1024 ? 1800 : 600;\ndurationSeconds = Math.Min(durationSeconds, maxWindowSec);","typeGuard":"null","tryCatchPattern":"try { return await runner.AlignAsync(audio, text, ct); }\ncatch (ForcedAlignerException ex) when (ex.Message.Contains(\"out of memory\")) {\n    // shrink and retry\n    return await runner.AlignAsync(audio, text, ct, windowFactor: 0.5);\n}","preventionTips":["Size windows conservatively for the host RAM; grow only if it works.","Run the aligner in a memory-limited container with headroom, not at the cap.","Log window length on each call to correlate OOM with size."],"tags":["subtitle-edit","forced-aligner","crispasr","out-of-memory","audio-windowing"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}