SubtitleEdit/subtitleedit · error · TimeoutException
"{process.StartInfo.FileName} {process.StartInfo.Arguments}"
Error message
"{process.StartInfo.FileName} {process.StartInfo.Arguments}" did not finish within {timeout.TotalSeconds:0} seconds and was killed. What it means
Thrown by the three-argument ProcessExtensions.StartAndWaitAsync(process, cancellationToken, timeout) when a started child process (typically ffmpeg or a TTS engine CLI) does not exit before the supplied TimeSpan deadline. The method builds a linked CancellationTokenSource that cancels after the timeout; when WaitForExitAsync is cancelled it kills the entire process tree and then distinguishes a user-initiated cancellation (re-thrown as OperationCanceledException) from a genuine overrun (re-thrown as this TimeoutException naming the exact command line). The goal (issue #12093) is to surface a wedged child — e.g. ffmpeg blocked on a stdin prompt — as an error instead of freezing the generation/merge pipeline forever.
Source
Thrown at src/ui/Features/Video/TextToSpeech/ProcessExtensions.cs:61
public static async Task StartAndWaitAsync(this Process process, CancellationToken cancellationToken, TimeSpan timeout)
{
process.StartProcess();
using var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
timeoutCts.CancelAfter(timeout);
try
{
await process.WaitForExitAsync(timeoutCts.Token);
}
catch (OperationCanceledException)
{
KillNoError(process);
if (cancellationToken.IsCancellationRequested)
{
throw; // user cancel - propagate as cancellation, not as a timeout
}
throw new TimeoutException(
$"\"{process.StartInfo.FileName} {process.StartInfo.Arguments}\" did not finish within {timeout.TotalSeconds:0} seconds and was killed.");
}
}
private static void KillNoError(Process process)
{
try
{
process.Kill(entireProcessTree: true);
}
catch
{
// best-effort - the process may have exited in the meantime
}
}
}
View on GitHub (pinned to 17a9f07487)
Solutions
- Inspect the tools log (Se.WriteToolsLog) for the exact command line that hung and reproduce it manually to see the prompt/blocker.
- Ensure ffmpeg/child arguments include -nostdin and -y so it never waits on the terminal.
- Increase the TimeSpan passed to StartAndWaitAsync for long-running operations (merge/generation of long videos).
- Verify the engine binary version matches expectations and the input file is not corrupt (ffprobe the source).
- If antivirus is interfering, add an exclusion for the SE temp/tools folder.
Example fix
// before await process.StartAndWaitAsync(process, ct, TimeSpan.FromSeconds(30)); // after - non-interactive args and a window sized to the work psi.Arguments = "-nostdin -y " + psi.Arguments; await process.StartAndWaitAsync(process, ct, TimeSpan.FromSeconds(300));
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure the child is non-interactive and the timeout fits the work before starting.
if (!process.StartInfo.Arguments.Contains("-nostdin"))
process.StartInfo.Arguments = "-nostdin -y " + process.StartInfo.Arguments;
var estimatedSeconds = Math.Max(60, sourceDurationSeconds * 2);
var timeout = TimeSpan.FromSeconds(estimatedSeconds); Try / catch
try
{
await process.StartAndWaitAsync(process, ct, timeout);
}
catch (TimeoutException ex)
{
SeLogger.Error(ex, "Timed out: " + ex.Message); // message already names the command
throw; // or surface to user and offer retry with a longer window
}
catch (OperationCanceledException) when (ct.IsCancellationRequested)
{
// user cancel - not a timeout
} Prevention
- Always pass -nostdin/-y to ffmpeg-style children so they never block on the terminal.
- Size the timeout to the workload (longer for HD/4K merge and remote TTS).
- Log the command line before StartAndWaitAsync so a timeout is reproducible.
When it happens
Trigger: Calling StartAndWaitAsync with a timeout where the child runs past the deadline: ffmpeg invoked without -nostdin so it blocks reading stdin; a TTS engine CLI waiting on an interactive prompt; an extremely long video with a too-short timeout; antivirus holding the child process; a network-dependent generation stalling.
Common situations: ffmpeg launched without -nostdin/-y on Windows where a console is attached; corrupted input media causing ffmpeg to loop; a slow remote TTS endpoint exceeding the configured window; an older/region-locked engine binary that hangs; timeout value set too low for HD/4K content.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- DashScope transcription timed out after {_settings.TimeoutSe
- crispasr (chatterbox) did not report healthy within 15 minut
- crispasr (cosyvoice3-tts) did not report healthy within {(al
- crispasr (f5-tts) did not report healthy within {(hasLocalTa
- crispasr (indextts) did not report healthy within {5|15} min
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/e6745044f31a8bc4.
Report an issue: GitHub.