{"record":{"id":"692dbef2bdef9a2a","repo":"SubtitleEdit/subtitleedit","slug":"ocr-model-name-not-found-in-llamacppserverman","errorCode":null,"errorMessage":"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}.","messagePattern":"OCR model '(.+?)' not found in (.+?)\\. Download one in Subtitle Edit \\(OCR window > llama\\.cpp\\) or pass a full path via --ocr-model\\. Curated models: (.+?)\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/seconv/Core/LlamaCppOcrEngine.cs","lineNumber":171,"sourceCode":"                {\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).\n            var model = LlamaCppServerManager.OcrModels.FirstOrDefault(m => m.FileName.Equals(name, StringComparison.OrdinalIgnoreCase))\n                        ?? LlamaCppServerManager.OcrModels.FirstOrDefault(m => m.FileName.Equals(name + \".gguf\", StringComparison.OrdinalIgnoreCase))\n                        ?? LlamaCppServerManager.OcrModels.FirstOrDefault(m => m.DisplayName.Equals(name, StringComparison.OrdinalIgnoreCase));\n            if (model == null || !LlamaCppServerManager.IsModelInstalled(model))\n            {\n                throw new InvalidOperationException(\n                    $\"OCR model '{name}' not found in {LlamaCppServerManager.GetAndCreateModelsFolder()}. \" +\n                    \"Download one in Subtitle Edit (OCR window > llama.cpp) or pass a full path via --ocr-model. \" +\n                    $\"Curated models: {curatedNames}.\");\n            }\n\n            return model;\n        }\n\n        // No model given: pick the first installed curated OCR model.\n        var installed = LlamaCppServerManager.OcrModels.FirstOrDefault(LlamaCppServerManager.IsModelInstalled);\n        if (installed == null)\n        {\n            throw new InvalidOperationException(\n                $\"No llama.cpp OCR model found in {LlamaCppServerManager.GetAndCreateModelsFolder()}. \" +\n                \"Download one in Subtitle Edit (OCR window > llama.cpp) or pass --ocr-model:<path.gguf>. \" +\n                $\"Curated models: {curatedNames}.\");\n        }\n","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/seconv/Core/LlamaCppOcrEngine.cs#L153-L189","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","solutions":["Download the model in the Subtitle Edit GUI (OCR window > llama.cpp) which places it in the correct folder.","Manually download the .gguf (and its mmproj sidecar) into the models folder shown in the error message, using the curated FileName.","Alternatively, pass a full path via --ocr-model=<full-path.gguf> to bypass the curated-name lookup."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"var model = LlamaCppServerManager.OcrModels.FirstOrDefault(m =>\n    m.FileName.Equals(name, StringComparison.OrdinalIgnoreCase) ||\n    m.FileName.Equals(name + \".gguf\", StringComparison.OrdinalIgnoreCase) ||\n    m.DisplayName.Equals(name, StringComparison.OrdinalIgnoreCase));\nif (model != null && !LlamaCppServerManager.IsModelInstalled(model))\n    Console.Error.WriteLine($\"Model '{name}' is not installed. Download it via SE GUI or pass full path.\");","typeGuard":"static bool IsCuratedModelInstalled(string name) => LlamaCppServerManager.OcrModels.Any(m => (m.FileName.Equals(name, StringComparison.OrdinalIgnoreCase) || m.DisplayName.Equals(name, StringComparison.OrdinalIgnoreCase)) && LlamaCppServerManager.IsModelInstalled(m));","tryCatchPattern":"try { var model = LlamaCppOcrEngine.ResolveModel(modelArg); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"not found in\"))\n{ /* download the curated model or pass a full path */ }","preventionTips":["Use IsModelInstalled to verify a curated model is present before referencing it by name.","Download models through the SE GUI to ensure correct placement.","As a fallback, always have a full-path .gguf option available."],"tags":["llama-cpp","model-not-installed","ocr","validation","model"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}