{"record":{"id":"571d33e33bb3c233","repo":"ocrmypdf/OCRmyPDF","slug":"required-fallback-font-not-found-font-path","errorCode":null,"errorMessage":"Required fallback font not found: {font_path}","messagePattern":"Required fallback font not found: (.+?)","errorType":"error_code","errorClass":"FileNotFoundError","httpStatus":null,"severity":"critical","filePath":"src/ocrmypdf/font/font_provider.py","lineNumber":114,"sourceCode":"        \"\"\"Initialize builtin font provider.\n\n        Args:\n            font_dir: Directory containing font files. If None, uses\n                      the default ocrmypdf/data directory.\n        \"\"\"\n        if font_dir is None:\n            font_dir = Path(__file__).parent.parent / \"data\"\n        self.font_dir = font_dir\n        self._fonts: dict[str, FontManager] = {}\n        self._load_fonts()\n\n    def _load_fonts(self) -> None:\n        \"\"\"Load available fonts, logging warnings for missing ones.\"\"\"\n        for font_name, font_file in self.FONT_FILES.items():\n            font_path = self.font_dir / font_file\n            if not font_path.exists():\n                if font_name == 'Occulta':\n                    raise FileNotFoundError(\n                        f\"Required fallback font not found: {font_path}\"\n                    )\n                log.warning(\n                    \"Font %s not found at %s - OCR output quality for some \"\n                    \"scripts may be affected\",\n                    font_name,\n                    font_path,\n                )\n                continue\n\n            try:\n                self._fonts[font_name] = FontManager(font_path)\n            except Exception as e:\n                if font_name == 'Occulta':\n                    raise ValueError(\n                        f\"Failed to load required fallback font {font_file}: {e}\"\n                    ) from e\n                log.warning(","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/ocrmypdf/OCRmyPDF/blob/5074a0b0e109362422b768fd271ed84bf717c4ec/src/ocrmypdf/font/font_provider.py#L96-L132","documentation":"FontProvider loads its bundled font table; Occulta (the glyphless 'invisible text' font used for the OCR sandwich) is mandatory. If Occulta's .ttf file is missing from the font directory, _load_fonts() raises FileNotFoundError during FontProvider construction.","triggerScenarios":"Instantiating FontProvider (directly or via a pipeline run) where font_dir lacks the Occulta font file — e.g. a broken package install or a custom font_dir passed without copying the bundled fonts.","commonSituations":"Partial wheel installs, pruning 'data files' from packages, or pointing font_dir at a directory that only has optional script fonts.","solutions":["Reinstall ocrmypdf cleanly (pip install --force-reinstall ocrmypdf) to restore bundled fonts.","If using a custom font_dir, copy the package's bundled font files (including Occulta) into it."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"from importlib.resources import files\np = files('ocrmypdf') / 'font'  # verify packaged fonts exist\nassert any('Occulta' in f.name for f in p.iterdir()), 'bundled Occulta.ttf missing'","typeGuard":null,"tryCatchPattern":"try:\n    provider = FontProvider(...)\nexcept FileNotFoundError as e:\n    if 'Required fallback font' in str(e):\n        reinstall_ocrmypdf()","preventionTips":["Don't prune package data files when slimming images.","Smoke-test FontProvider construction after install."],"tags":["ocrmypdf","fonts","missing-file","packaging"],"backgroundTag":"missing-packaged-resource","analyzedSha":"5074a0b0e109362422b768fd271ed84bf717c4ec","analyzedAt":"2026-08-27T11:57:38.523Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}