SubtitleEdit/subtitleedit · error · Exception

{engine.Error}

Error message

{engine.Error}

What it means

Thrown in OcrGroupsWithCrispEmbed after attempting to start the CrispEmbed engine: StartCliPipeline (for detector+recognizer backends) or StartServerAsync (for VLM backends) returned false, and engine.Error holds the reason. A false return means the server/CLI process could not be launched or did not become ready, so scanning frames is impossible and the method aborts before RunLlmOcr.

Source

Thrown at src/ui/Features/Video/VideoOcr/VideoOcrViewModel.cs:1015

        {
            throw new Exception(Se.Language.Ocr.CrispEmbedNotDownloaded);
        }

        using var engine = new CrispEmbedOcr(Se.Settings.Ocr.CrispEmbedOcrTimeoutMinutes);

        var started = backend.UsesTextDetector
            ? engine.StartCliPipeline(
                CrispEmbedEngine.GetCliExecutable(),
                backend.GetModelPath(model.Model),
                backend.GetDetectorPath(model.Model))
            : await engine.StartServerAsync(
                CrispEmbedEngine.GetServerExecutable(),
                backend.GetModelPath(model.Model),
                cancellationToken);

        if (!started)
        {
            throw new Exception(engine.Error);
        }

        await RunLlmOcr(ocrGroups, group => OcrWithBitmap(group, bitmap => engine.Ocr(bitmap, cancellationToken)),
            () => engine.Error, reportProgress, addPreviewLine, cancellationToken);
    }

    private static async Task<string> OcrWithBitmap(VideoOcrFrameGroup group, Func<SKBitmap, Task<string>> ocr)
    {
        using var bitmap = SKBitmap.Decode(group.RepresentativeFileName);
        if (bitmap == null)
        {
            return string.Empty;
        }

        return await ocr(bitmap);
    }

    private static async Task RunLlmOcr(

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Read engine.Error in the exception message for the concrete startup failure.
  2. Confirm CrispEmbedEngine.GetCliExecutable()/GetServerExecutable() return existing, executable files.
  3. Verify backend.GetModelPath/GetDetectorPath point at complete (non-partial) model files; re-download if needed.
  4. Free the server port / kill stale crispembed-server processes, and ensure the required runtime (CUDA/CPU) is installed.

Example fix

// before
var started = backend.UsesTextDetector
    ? engine.StartCliPipeline(CrispEmbedEngine.GetCliExecutable(), backend.GetModelPath(model.Model), backend.GetDetectorPath(model.Model))
    : await engine.StartServerAsync(CrispEmbedEngine.GetServerExecutable(), backend.GetModelPath(model.Model), cancellationToken);
if (!started) throw new Exception(engine.Error);

// after - preflight paths so the error names the missing file
var cli = CrispEmbedEngine.GetCliExecutable();
var modelPath = backend.GetModelPath(model.Model);
if (!File.Exists(cli)) throw new Exception("CrispEmbed CLI not found: " + cli);
if (!File.Exists(modelPath)) throw new Exception("CrispEmbed model not found: " + modelPath);
var started = backend.UsesTextDetector
    ? engine.StartCliPipeline(cli, modelPath, backend.GetDetectorPath(model.Model))
    : await engine.StartServerAsync(CrispEmbedEngine.GetServerExecutable(), modelPath, cancellationToken);
if (!started) throw new Exception(engine.Error);
Defensive patterns

Strategy: validation

Validate before calling

var cli = CrispEmbedEngine.GetCliExecutable();
var modelPath = backend.GetModelPath(model.Model);
if (!File.Exists(cli)) throw new Exception("CrispEmbed CLI not found: " + cli);
if (!File.Exists(modelPath)) throw new Exception("CrispEmbed model not found: " + modelPath);

Try / catch

try
{
    var started = backend.UsesTextDetector ? engine.StartCliPipeline(...) : await engine.StartServerAsync(...);
    if (!started) throw new Exception(engine.Error);
}
catch (Exception ex) { SeLogger.Error(ex, "CrispEmbed engine failed to start"); /* show message */ }

Prevention

When it happens

Trigger: CrispEmbed CLI executable or server executable missing/not executable; the model/detector path is wrong or the file is corrupt; the server failed to bind its port or crashed during startup; a timeout waiting for the server to become ready; missing runtime dependency (e.g. CUDA/runtime for the GGUF).

Common situations: Backend chosen but its executable was deleted/renamed; model download incomplete so GetModelPath points at a partial file; port already in use by a stale server process; GPU runtime missing for a GPU backend.

Related errors


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