SubtitleEdit/subtitleedit · error · InvalidOperationException
No vision projector found next to {fullPath}. llama.cpp OCR
Error message
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. What it means
Thrown when a full .gguf model path exists (File.Exists passes) but no mmproj vision-projector sidecar file is found next to it. llama.cpp vision/OCR models need both the main model and a projector file; without the projector the model cannot process images at all. The engine searches for two naming conventions: 'mmproj-<filename>' (e.g. mmproj-model.gguf) and '<stem>-mmproj.gguf' (e.g. model-mmproj.gguf) in the same directory.
Source
Thrown at src/seconv/Core/LlamaCppOcrEngine.cs:156
{
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).
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}.");View on GitHub (pinned to 17a9f07487)
Solutions
- Download the mmproj sidecar from the same model page and place it next to the main .gguf, named either 'mmproj-<filename>' or '<stem>-mmproj.gguf'.
- If the sidecar has a different name, rename it to match one of the two expected conventions.
- Verify both files exist in the same directory with a directory listing before running OCR.
Defensive patterns
Strategy: validation
Validate before calling
static string? FindMmproj(string modelPath)
{
var dir = Path.GetDirectoryName(modelPath)!;
var fileName = Path.GetFileName(modelPath);
var stem = Path.GetFileNameWithoutExtension(modelPath);
return new[] { $"mmproj-{fileName}", $"{stem}-mmproj.gguf" }
.Select(n => Path.Combine(dir, n))
.FirstOrDefault(File.Exists);
}
// Before ResolveModel:
if (FindMmproj(fullPath) == null)
Console.Error.WriteLine("Missing mmproj sidecar — download and place it next to the model."); Type guard
static bool HasMmprojSidecar(string modelPath) => FindMmproj(modelPath) != null;
Try / catch
try { var model = LlamaCppOcrEngine.ResolveModel(modelArg); }
catch (InvalidOperationException ex) when (ex.Message.Contains("No vision projector found"))
{ /* download mmproj sidecar and place next to model */ } Prevention
- Always download both the main model .gguf and its mmproj sidecar from the same model page.
- Keep the mmproj file in the same directory as the model, following the expected naming convention.
- After downloading, list the model directory to verify both files are present.
When it happens
Trigger: Downloading only the main .gguf model without its mmproj sidecar; the sidecar has an unexpected name that matches neither convention; the sidecar is in a different directory than the model.
Common situations: Downloading a vision model from HuggingFace and missing the separate mmproj file download link; renaming the model file without renaming the sidecar; the model download was incomplete.
Related errors
- llama-server not found. Either: download llama.cpp in Subtit
- OCR model file not found: {name}
- OCR model '{name}' not found in {LlamaCppServerManager.GetAn
- No llama.cpp OCR model found in {LlamaCppServerManager.GetAn
- CrispASR MADLAD model not found - please use the 'Download'
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/82b67448e37dbf80.
Report an issue: GitHub.