{"record":{"id":"0fa6e7791e14b1a3","repo":"ocrmypdf/OCRmyPDF","slug":"no-fallback-font-available-from-any-provider","errorCode":null,"errorMessage":"No fallback font available from any provider","messagePattern":"No fallback font available from any provider","errorType":"error_code","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/ocrmypdf/font/font_provider.py","lineNumber":248,"sourceCode":"        return None\n\n    def get_fallback_font(self) -> FontManager:\n        \"\"\"Get the glyphless fallback font.\n\n        Tries each provider until one provides a fallback font.\n\n        Returns:\n            FontManager for the fallback font\n\n        Raises:\n            RuntimeError: If no provider can provide a fallback font\n        \"\"\"\n        for provider in self.providers:\n            try:\n                return provider.get_fallback_font()\n            except (NotImplementedError, AttributeError, KeyError):\n                continue\n        raise RuntimeError(\"No fallback font available from any provider\")\n","sourceCodeStart":230,"sourceCodeEnd":249,"githubUrl":"https://github.com/ocrmypdf/OCRmyPDF/blob/5074a0b0e109362422b768fd271ed84bf717c4ec/src/ocrmypdf/font/font_provider.py#L230-L249","documentation":"get_fallback_font() iterates all registered providers calling get_fallback_font(); providers that don't implement it raise NotImplementedError/AttributeError/KeyError which are skipped. If every provider is exhausted, RuntimeError indicates no glyphless fallback (Occulta) could be supplied by any configured provider.","triggerScenarios":"Building a chain of only SystemFontProvider (or other providers without fallback support) and calling get_fallback_font() — common when assembling PDFs with visible/OCR text.","commonSituations":"Custom plugin setups that prefer system fonts and drop BuiltinFontProvider; sandboxed environments where the builtin font dir was excluded.","solutions":["Add BuiltinFontProvider to the providers list so Occulta.ttf is available.","If you only render non-sandwich output, avoid calling get_fallback_font() in that code path."],"exampleFix":"# before\nchain = FontProviderChain([SystemFontProvider(font_dir)])\nfont = chain.get_fallback_font()\n# after\nchain = FontProviderChain([SystemFontProvider(font_dir), BuiltinFontProvider(builtin_dir)])\nfont = chain.get_fallback_font()","handlingStrategy":"fallback","validationCode":"has_fallback = any(\n    hasattr(p, 'get_fallback_font') and not getattr(p, 'NO_FALLBACK', False)\n    for p in chain.providers\n)\nassert has_fallback, 'add BuiltinFontProvider for Occulta fallback'","typeGuard":null,"tryCatchPattern":"try:\n    font = chain.get_fallback_font()\nexcept RuntimeError:\n    font = BuiltinFontProvider(builtin_dir).get_fallback_font()","preventionTips":["Always include BuiltinFontProvider in custom provider chains.","Reserve get_fallback_font() for sandwich/OCR rendering paths only."],"tags":["ocrmypdf","fonts","fallback-font","provider-chain"],"backgroundTag":"no-fallback-font-available","analyzedSha":"5074a0b0e109362422b768fd271ed84bf717c4ec","analyzedAt":"2026-08-27T11:57:38.523Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}