SubtitleEdit/subtitleedit · error · InvalidOperationException
OCR model file not found: {name}
Error message
OCR model file not found: {name} What it means
Thrown when the --ocr-model argument is a path (rooted or containing a directory separator) pointing to a .gguf model file, but that file does not exist (File.Exists returns false). The OCR engine resolves paths directly — a non-existent model file path is an immediate hard failure since there is nothing to load.
Source
Thrown at src/seconv/Core/LlamaCppOcrEngine.cs:147
/// Resolves <c>--ocr-model</c> to an installed model: a full <c>.gguf</c> path (needs its
/// mmproj vision-projector sidecar next to it), a curated OCR model by file/display name,
/// or - when omitted - the first installed curated OCR model.
/// </summary>
internal static LlamaCppModel ResolveOcrModel(string? requestedModel)
{
var curatedNames = string.Join(", ", LlamaCppServerManager.OcrModels.Select(m => m.FileName));
if (!string.IsNullOrWhiteSpace(requestedModel))
{
var name = requestedModel.Trim();
// Full path to a .gguf: use it directly, but require the mmproj sidecar - a vision
// model served without its projector can't see the image at all.
if (Path.IsPathRooted(name) || name.Contains(Path.DirectorySeparatorChar) || name.Contains(Path.AltDirectorySeparatorChar))
{
if (!File.Exists(name))
{
throw new InvalidOperationException($"OCR model file not found: {name}");
}
var fullPath = Path.GetFullPath(name);
var mmproj = FindMmprojSidecar(fullPath);
if (mmproj == null)
{
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).View on GitHub (pinned to 17a9f07487)
Solutions
- Verify the path with File.Exists before passing it; check for typos and correct the directory.
- Use an absolute path to avoid working-directory ambiguity: --ocr-model=/home/user/models/model.gguf.
- Alternatively, pass just the curated model name (without directory separators) to let seconv resolve it from the models folder.
Example fix
// before
var model = LlamaCppOcrEngine.ResolveModel("/wrong/path/model.gguf");
// after
var model = LlamaCppOcrEngine.ResolveModel("/correct/path/model.gguf"); Defensive patterns
Strategy: validation
Validate before calling
if (Path.IsPathRooted(name) || name.Contains(Path.DirectorySeparatorChar))
{
if (!File.Exists(name))
throw new InvalidOperationException($"OCR model file not found: {name}");
} Type guard
static bool IsModelFileReadable(string name) => !Path.IsPathRooted(name) && !name.Contains(Path.DirectorySeparatorChar) || File.Exists(name);
Try / catch
try { var model = LlamaCppOcrEngine.ResolveModel(modelArg); }
catch (InvalidOperationException ex) when (ex.Message.Contains("OCR model file not found"))
{ /* correct the path or use a curated model name */ } Prevention
- Use absolute paths for --ocr-model to avoid CWD ambiguity.
- Validate File.Exists for model paths before passing them.
- Prefer curated model names when possible to let seconv handle path resolution.
When it happens
Trigger: Passing --ocr-model=/path/to/model.gguf where the path is wrong, the file was deleted, or the relative path resolved from an unexpected working directory. The path is detected as a full/relative file path (via Path.IsPathRooted or directory separator presence) rather than a curated model name.
Common situations: Typo in the model path; the model was downloaded to a different directory; a relative path that breaks when CWD changes; pointing at a symlink that dangles.
Related errors
- OCR model '{name}' not found in {LlamaCppServerManager.GetAn
- Subtitle file not found: {filePath}
- EBU header file not found: {ebuHeaderFile}
- ASSA style file not found: {assaStyleFile}
- No vision projector found next to {fullPath}. llama.cpp OCR
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/f37279239e424fc0.
Report an issue: GitHub.