SubtitleEdit/subtitleedit · error · InvalidOperationException

OCR model '{name}' not found in {LlamaCppServerManager.GetAn

Error message

OCR model '{name}' not found in {LlamaCppServerManager.GetAndCreateModelsFolder()}. Download one in Subtitle Edit (OCR window > llama.cpp) or pass a full path via --ocr-model. Curated models: {curatedNames}.

What it means

Thrown when --ocr-model is passed as a bare name (not a path) matching a curated OCR model's file or display name, but that model is not installed (IsModelInstalled returns false). The curated model list (LlamaCppServerManager.OcrModels) defines which models seconv knows about; IsModelInstalled checks if the .gguf is actually present in the models folder. The message includes the models folder path and the list of curated model names.

Source

Thrown at src/seconv/Core/LlamaCppOcrEngine.cs:171

                {
                    var fileName = Path.GetFileName(fullPath);
                    var stem = Path.GetFileNameWithoutExtension(fullPath);
                    throw new InvalidOperationException(
                        $"No vision projector found next to {fullPath}. llama.cpp OCR models need their mmproj sidecar; " +
                        $"expected 'mmproj-{fileName}' or '{stem}-mmproj.gguf' in the same folder.");
                }

                return new LlamaCppModel(Path.GetFileName(fullPath), fullPath, string.Empty, Url: string.Empty,
                    MmprojFileName: mmproj);
            }

            // Name: match the curated OCR models (with or without .gguf).
            var model = LlamaCppServerManager.OcrModels.FirstOrDefault(m => m.FileName.Equals(name, StringComparison.OrdinalIgnoreCase))
                        ?? LlamaCppServerManager.OcrModels.FirstOrDefault(m => m.FileName.Equals(name + ".gguf", StringComparison.OrdinalIgnoreCase))
                        ?? LlamaCppServerManager.OcrModels.FirstOrDefault(m => m.DisplayName.Equals(name, StringComparison.OrdinalIgnoreCase));
            if (model == null || !LlamaCppServerManager.IsModelInstalled(model))
            {
                throw new InvalidOperationException(
                    $"OCR model '{name}' not found in {LlamaCppServerManager.GetAndCreateModelsFolder()}. " +
                    "Download one in Subtitle Edit (OCR window > llama.cpp) or pass a full path via --ocr-model. " +
                    $"Curated models: {curatedNames}.");
            }

            return model;
        }

        // No model given: pick the first installed curated OCR model.
        var installed = LlamaCppServerManager.OcrModels.FirstOrDefault(LlamaCppServerManager.IsModelInstalled);
        if (installed == null)
        {
            throw new InvalidOperationException(
                $"No llama.cpp OCR model found in {LlamaCppServerManager.GetAndCreateModelsFolder()}. " +
                "Download one in Subtitle Edit (OCR window > llama.cpp) or pass --ocr-model:<path.gguf>. " +
                $"Curated models: {curatedNames}.");
        }

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Download the model in the Subtitle Edit GUI (OCR window > llama.cpp) which places it in the correct folder.
  2. Manually download the .gguf (and its mmproj sidecar) into the models folder shown in the error message, using the curated FileName.
  3. Alternatively, pass a full path via --ocr-model=<full-path.gguf> to bypass the curated-name lookup.
Defensive patterns

Strategy: validation

Validate before calling

var model = LlamaCppServerManager.OcrModels.FirstOrDefault(m =>
    m.FileName.Equals(name, StringComparison.OrdinalIgnoreCase) ||
    m.FileName.Equals(name + ".gguf", StringComparison.OrdinalIgnoreCase) ||
    m.DisplayName.Equals(name, StringComparison.OrdinalIgnoreCase));
if (model != null && !LlamaCppServerManager.IsModelInstalled(model))
    Console.Error.WriteLine($"Model '{name}' is not installed. Download it via SE GUI or pass full path.");

Type guard

static bool IsCuratedModelInstalled(string name) => LlamaCppServerManager.OcrModels.Any(m => (m.FileName.Equals(name, StringComparison.OrdinalIgnoreCase) || m.DisplayName.Equals(name, StringComparison.OrdinalIgnoreCase)) && LlamaCppServerManager.IsModelInstalled(m));

Try / catch

try { var model = LlamaCppOcrEngine.ResolveModel(modelArg); }
catch (InvalidOperationException ex) when (ex.Message.Contains("not found in"))
{ /* download the curated model or pass a full path */ }

Prevention

When it happens

Trigger: Passing --ocr-model=<name> where <name> matches a curated model's FileName (with or without .gguf) or DisplayName, but the model file has not been downloaded into GetAndCreateModelsFolder().

Common situations: Referencing a curated model by name before downloading it; a model that was downloaded but to the wrong folder or later deleted; using a display name from documentation that doesn't match the installed file.

Related errors


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