{"record":{"id":"f37279239e424fc0","repo":"SubtitleEdit/subtitleedit","slug":"ocr-model-file-not-found-name","errorCode":null,"errorMessage":"OCR model file not found: {name}","messagePattern":"OCR model file not found: (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/seconv/Core/LlamaCppOcrEngine.cs","lineNumber":147,"sourceCode":"    /// Resolves <c>--ocr-model</c> to an installed model: a full <c>.gguf</c> path (needs its\n    /// mmproj vision-projector sidecar next to it), a curated OCR model by file/display name,\n    /// or - when omitted - the first installed curated OCR model.\n    /// </summary>\n    internal static LlamaCppModel ResolveOcrModel(string? requestedModel)\n    {\n        var curatedNames = string.Join(\", \", LlamaCppServerManager.OcrModels.Select(m => m.FileName));\n\n        if (!string.IsNullOrWhiteSpace(requestedModel))\n        {\n            var name = requestedModel.Trim();\n\n            // Full path to a .gguf: use it directly, but require the mmproj sidecar - a vision\n            // model served without its projector can't see the image at all.\n            if (Path.IsPathRooted(name) || name.Contains(Path.DirectorySeparatorChar) || name.Contains(Path.AltDirectorySeparatorChar))\n            {\n                if (!File.Exists(name))\n                {\n                    throw new InvalidOperationException($\"OCR model file not found: {name}\");\n                }\n\n                var fullPath = Path.GetFullPath(name);\n                var mmproj = FindMmprojSidecar(fullPath);\n                if (mmproj == null)\n                {\n                    var fileName = Path.GetFileName(fullPath);\n                    var stem = Path.GetFileNameWithoutExtension(fullPath);\n                    throw new InvalidOperationException(\n                        $\"No vision projector found next to {fullPath}. llama.cpp OCR models need their mmproj sidecar; \" +\n                        $\"expected 'mmproj-{fileName}' or '{stem}-mmproj.gguf' in the same folder.\");\n                }\n\n                return new LlamaCppModel(Path.GetFileName(fullPath), fullPath, string.Empty, Url: string.Empty,\n                    MmprojFileName: mmproj);\n            }\n\n            // Name: match the curated OCR models (with or without .gguf).","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/seconv/Core/LlamaCppOcrEngine.cs#L129-L165","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nvar model = LlamaCppOcrEngine.ResolveModel(\"/wrong/path/model.gguf\");\n\n// after\nvar model = LlamaCppOcrEngine.ResolveModel(\"/correct/path/model.gguf\");","handlingStrategy":"validation","validationCode":"if (Path.IsPathRooted(name) || name.Contains(Path.DirectorySeparatorChar))\n{\n    if (!File.Exists(name))\n        throw new InvalidOperationException($\"OCR model file not found: {name}\");\n}","typeGuard":"static bool IsModelFileReadable(string name) => !Path.IsPathRooted(name) && !name.Contains(Path.DirectorySeparatorChar) || File.Exists(name);","tryCatchPattern":"try { var model = LlamaCppOcrEngine.ResolveModel(modelArg); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"OCR model file not found\"))\n{ /* correct the path or use a curated model name */ }","preventionTips":["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."],"tags":["llama-cpp","file-not-found","ocr","validation","path","model"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}