SubtitleEdit/subtitleedit · error · Exception

{Se.Language.Ocr.CrispEmbedNotDownloaded}

Error message

{Se.Language.Ocr.CrispEmbedNotDownloaded}

What it means

Thrown at the top of OcrGroupsWithCrispEmbed when either SelectedCrispEmbedBackend or SelectedCrispEmbedModel is null — the pattern `is not { } backend || ... is not { } model` fails. With no backend+model selected the method cannot locate an executable or model path, so it aborts immediately with the localized 'CrispEmbedNotDownloaded' message rather than passing nulls into CrispEmbedEngine.GetCliExecutable/GetServerExecutable.

Source

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

        }
    }

    /// <summary>
    /// Runs the frame groups through CrispEmbed. The VLM backends load the GGUF into one
    /// crispembed-server instance that stays up for the whole scan - a video produces hundreds of
    /// groups and the model load alone is seconds, so starting a server per frame would be
    /// unusable. PP-OCRv6 is a detector+recognizer pair driven through the CLI instead, one
    /// invocation per frame, which is what <see cref="CrispEmbedOcr"/> expects.
    /// </summary>
    private async Task OcrGroupsWithCrispEmbed(
        List<VideoOcrFrameGroup> ocrGroups,
        Action reportProgress,
        Action<VideoOcrFrameGroup> addPreviewLine,
        CancellationToken cancellationToken)
    {
        if (SelectedCrispEmbedBackend is not { } backend || SelectedCrispEmbedModel is not { } model)
        {
            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);
        }

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Open the CrispEmbed settings and download then select a backend and a model before starting OCR.
  2. Run the EnsureCrispEmbedReady preflight (called from EnsureEngineIsAvailable) so the engine is validated before OcrGroupsWithCrispEmbed is reached.
  3. If a download was interrupted, remove the partial model and re-download.

Example fix

// before
if (SelectedCrispEmbedBackend is not { } backend || SelectedCrispEmbedModel is not { } model)
    throw new Exception(Se.Language.Ocr.CrispEmbedNotDownloaded);

// after - block at the command layer so the user gets a guided fix, not a throw
if (SelectedCrispEmbedBackend is null || SelectedCrispEmbedModel is null)
{
    await MessageBox.Show(Window!, Se.Language.General.Error,
        "Download and select a CrispEmbed backend and model first.",
        MessageBoxButtons.OK, MessageBoxIcon.Error);
    return;
}
Defensive patterns

Strategy: validation

Validate before calling

if (SelectedCrispEmbedBackend is null || SelectedCrispEmbedModel is null)
{
    await MessageBox.Show(Window!, Se.Language.General.Error,
        "Download and select a CrispEmbed backend and model first.",
        MessageBoxButtons.OK, MessageBoxIcon.Error);
    return;
}

Prevention

When it happens

Trigger: User chose the CrispEmbed OCR engine but never downloaded/selected a backend or model, or a previously selected model was removed and the selection reset to null before the scan started.

Common situations: First use of CrispEmbed with nothing downloaded; a model download was interrupted leaving the entry null; the backend/model dropdowns were cleared by a settings reset.

Related errors


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