ocrmypdf/OCRmyPDF · error · BadArgsError

The following languages are for Tesseract's internal use and

Error message

The following languages are for Tesseract's internal use and should not be issued explicitly: {', '.join(DENIED_LANGUAGES & set(languages))}\nRemove them from the -l/--language argument.

What it means

Tesseract language codes 'equ' (equations) and 'osd' (orientation/script detection) are not real OCR languages — Tesseract runs them internally for specific features. validate_with_context() raises BadArgsError if they appear in the requested language list.

Source

Thrown at src/ocrmypdf/builtin_plugins/tesseract_ocr.py:286

    def validate_downsample_consistency(self):
        """Validate downsample options are consistent."""
        if self.downsample_above != 32767 and not self.downsample_large_images:
            log.warning(
                "The --tesseract-downsample-above argument will have no effect unless "
                "--tesseract-downsample-large-images is also given."
            )
        return self

    def validate_with_context(self, languages: list[str]) -> None:
        """Validate options that require external context.

        Args:
            languages: List of languages being used for OCR
        """
        # Validate languages are not internal Tesseract languages
        DENIED_LANGUAGES = {'equ', 'osd'}
        if DENIED_LANGUAGES & set(languages):
            raise BadArgsError(
                "The following languages are for Tesseract's internal use "
                "and should not be issued explicitly: "
                f"{', '.join(DENIED_LANGUAGES & set(languages))}\n"
                "Remove them from the -l/--language argument."
            )


@hookimpl
def register_options():
    """Register Tesseract option model."""
    return {'tesseract': TesseractOptions}


@hookimpl
def add_options(parser):
    # Use the model's CLI generation method - it now handles all Tesseract options
    TesseractOptions.add_arguments_to_parser(parser)

View on GitHub (pinned to 5074a0b0e1)

Solutions

  1. Remove equ/osd from the language argument; use only real traineddata languages (eng, deu, ...).
  2. For orientation detection rely on ocrmypdf's rotate/deskew options, which invoke osd internally themselves.

Example fix

# before
ocr(in, out, language='eng+osd')
# after
ocr(in, out, language='eng')
Defensive patterns

Strategy: validation

Validate before calling

DENIED = {'equ', 'osd'}
langs = languages if isinstance(languages, list) else languages.split('+')
assert not (DENIED & set(langs)), 'equ/osd are internal Tesseract codes'

Type guard

def is_valid_language_list(langs: list[str]) -> bool:
    return not ({'equ','osd'} & set(langs))

Prevention

When it happens

Trigger: Passing language=['eng','osd'] or -l eng+equ to ocr()/the CLI.

Common situations: Users copying a language string from a Tesseract tutorial that includes osd; trying to 'force' orientation detection via -l.

Related errors


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