{"record":{"id":"7b54e61399cd03ae","repo":"ocrmypdf/OCRmyPDF","slug":"systemfontprovider-does-not-provide-a-fallback-fon","errorCode":null,"errorMessage":"SystemFontProvider does not provide a fallback font. Use BuiltinFontProvider for Occulta.ttf fallback.","messagePattern":"SystemFontProvider does not provide a fallback font\\. Use BuiltinFontProvider for Occulta\\.ttf fallback\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"warning","filePath":"src/ocrmypdf/font/system_font_provider.py","lineNumber":560,"sourceCode":"        \"\"\"Get list of font names this provider can potentially find.\n\n        Note: This returns all font names we know patterns for, not\n        necessarily fonts that are actually installed. Use get_font()\n        to check if a specific font is available.\n\n        Returns:\n            List of logical font names\n        \"\"\"\n        return list(self.NOTO_FONT_PATTERNS.keys())\n\n    def get_fallback_font(self) -> FontManager:\n        \"\"\"Get the glyphless fallback font.\n\n        Raises:\n            NotImplementedError: System provider doesn't provide fallback.\n                Use BuiltinFontProvider for the fallback font.\n        \"\"\"\n        raise NotImplementedError(\n            \"SystemFontProvider does not provide a fallback font. \"\n            \"Use BuiltinFontProvider for Occulta.ttf fallback.\"\n        )\n","sourceCodeStart":542,"sourceCodeEnd":564,"githubUrl":"https://github.com/ocrmypdf/OCRmyPDF/blob/5074a0b0e109362422b768fd271ed84bf717c4ec/src/ocrmypdf/font/system_font_provider.py#L542-L564","documentation":"SystemFontProvider enumerates fonts installed on the OS; it deliberately does not ship or resolve the glyphless 'Occulta' fallback used for invisible OCR text, so get_fallback_font() always raises NotImplementedError, directing you to BuiltinFontProvider.","triggerScenarios":"Calling SystemFontProvider.get_fallback_font() directly, or a chain that surfaces the exception when fallback handling isn't configured to skip it.","commonSituations":"Custom font code assuming any provider can yield a fallback; catching only some exception types so NotImplementedError escapes.","solutions":["Use BuiltinFontProvider (bundled Occulta.ttf) for the fallback font.","If iterating a chain, treat NotImplementedError as 'skip this provider' rather than an error."],"exampleFix":"# before\nfallback = system_font_provider.get_fallback_font()\n# after\nfallback = BuiltinFontProvider(builtin_font_dir).get_fallback_font()","handlingStrategy":"type-guard","validationCode":"from ocrmypdf.font.builtin_font_provider import BuiltinFontProvider\nif isinstance(provider, SystemFontProvider):\n    fallback = BuiltinFontProvider(...).get_fallback_font()\nelse:\n    fallback = provider.get_fallback_font()","typeGuard":"def provider_has_fallback(provider) -> bool:\n    return not provider.__class__.__name__.startswith('System')  # or check explicitly","tryCatchPattern":"try:\n    provider.get_fallback_font()\nexcept NotImplementedError:\n    provider = BuiltinFontProvider(...); fallback = provider.get_fallback_font()","preventionTips":["Never assume every provider implements the fallback API; document capability per provider.","Skip NotImplementedError providers when iterating chains."],"tags":["ocrmypdf","fonts","not-implemented","system-fonts"],"backgroundTag":"unsupported-operation-misconfiguration","analyzedSha":"5074a0b0e109362422b768fd271ed84bf717c4ec","analyzedAt":"2026-08-27T11:57:38.523Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}