ocrmypdf/OCRmyPDF · error · ValueError

At least one provider is required

Error message

At least one provider is required

What it means

The font resolution chain (FontProviderChain-like class) tries providers in order; constructing it with an empty providers list is rejected immediately with ValueError('At least one provider is required').

Source

Thrown at src/ocrmypdf/font/font_provider.py:179


class ChainedFontProvider:
    """Font provider that tries multiple providers in order.

    This allows combining builtin fonts with system fonts, trying
    the builtin provider first and falling back to system fonts
    for fonts not bundled with the package.
    """

    def __init__(self, providers: list[FontProvider]):
        """Initialize chained font provider.

        Args:
            providers: List of font providers to try in order.
                       The first provider that returns a font wins.
        """
        if not providers:
            raise ValueError("At least one provider is required")
        self.providers = providers

    def get_font(self, font_name: str) -> FontManager | None:
        """Get a FontManager for the named font.

        Tries each provider in order until one returns a font.

        Args:
            font_name: Logical font name (e.g., 'NotoSans-Regular')

        Returns:
            FontManager if any provider has the font, None otherwise
        """
        for provider in self.providers:
            if font := provider.get_font(font_name):
                return font
        return None

View on GitHub (pinned to 5074a0b0e1)

Solutions

  1. Ensure at least BuiltinFontProvider is included in the providers list.
  2. Fix the logic producing the empty list (check flags/conditions used to filter providers).

Example fix

# before
providers = [p for p in candidates if p]
chain = FontProviderChain(providers)  # may be empty
# after
providers = [p for p in candidates if p] or [BuiltinFontProvider()]
chain = FontProviderChain(providers)
Defensive patterns

Strategy: validation

Validate before calling

assert providers, 'at least one font provider required'

Type guard

def has_provider(providers: list) -> bool:
    return len(providers) > 0

Prevention

When it happens

Trigger: new FontProviderChain([]) — typically when a caller builds the provider list conditionally and every branch returned nothing (e.g. system fonts disabled and builtin provider skipped).

Common situations: Feature-flag combinations that filter out all providers; upstream code changes returning an empty list where one provider was expected.

Related errors


AI-assisted analysis of ocrmypdf/OCRmyPDF@5074a0b0e1 (2026-08-27). Data as JSON: /api/errors/849b7a34e9f0f21b. Report an issue: GitHub.