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

  1. Inspect the tools log (Se.WriteToolsLog) for the exact command line that hung and reproduce it manually to see the prompt/blocker.
  2. Ensure ffmpeg/child arguments include -nostdin and -y so it never waits on the terminal.
  3. Increase the TimeSpan passed to StartAndWaitAsync for long-running operations (merge/generation of long videos).
  4. Verify the engine binary version matches expectations and the input file is not corrupt (ffprobe the source).
  5. 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

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

Related errors


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