zylon-ai/private-gpt · error · ValueError

Language {lang} not supported by RapidOCR

Error message

Language {lang} not supported by RapidOCR

What it means

Raised by convert_to_rapidocr_lang in docling/utils.py when the language code is not a key of LANG_TO_RAPIDOCR. RapidOCR uses full language names ('english', 'chinese') rather than codes, so docling.langs entries are translated through LANG_TO_RAPIDOCR; unknown keys fail fast with the chained KeyError preserved.

Source

Thrown at private_gpt/components/readers/docling/utils.py:133

        raise ValueError(f"Language {lang} not supported by Tesseract") from e


def convert_to_rapidocr_lang(lang: str) -> str:
    """Convert language code to RapidOCR format.

    Args:
        lang: Language code in format like 'en-US', 'es-ES'

    Returns:
        Language name in RapidOCR format (e.g., 'english', 'chinese')

    Raises:
        ValueError: If language is not supported
    """
    try:
        return LANG_TO_RAPIDOCR[lang]
    except KeyError as e:
        raise ValueError(f"Language {lang} not supported by RapidOCR") from e


def convert_to_ocrmac_lang(lang: str) -> str:
    """Convert language code to OCRMac format.

    Args:
        lang: Language code in format like 'en-US', 'es-ES'

    Returns:
        Language code in OCRMac format (usually same as input)

    Raises:
        ValueError: If language is not supported
    """
    try:
        # Do nothing
        return lang
    except KeyError as e:

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Check LANG_TO_RAPIDOCR in utils.py and restrict docling.langs to its keys when using rapidocr.
  2. If you need broader language coverage, switch ocr_model back to easyocr or tesseract.
  3. Split corpora: route documents by language to different ocr_model settings if you ingest multilingual archives.

Example fix

# settings.yaml — before
# docling:
#   ocr_model: rapidocr
#   langs: [en-US, de-DE]

# after (only mapped languages)
# docling:
#   ocr_model: rapidocr
#   langs: [en-US]
# or switch engine for wider coverage
#   ocr_model: tesseract
#   langs: [en-US, de-DE]
Defensive patterns

Strategy: validation

Validate before calling

from private_gpt.components.readers.docling.utils import LANG_TO_RAPIDOCR

def validate_rapidocr_langs(langs: list[str]) -> None:
    bad = [l for l in langs if l not in LANG_TO_RAPIDOCR]
    if bad:
        raise SystemExit(f"langs {bad} unsupported by rapidocr (small language set); consider tesseract/easyocr")

validate_rapidocr_langs(settings().docling.langs or [])

Type guard

from private_gpt.components.readers.docling.utils import LANG_TO_RAPIDOCR

def is_rapidocr_lang(lang: str) -> bool:
    return lang in LANG_TO_RAPIDOCR

Try / catch

try:
    r = [convert_to_rapidocr_lang(l) for l in langs]
except ValueError as e:
    if "not supported by RapidOCR" in str(e):
        # fall back to a wider-coverage engine for this corpus
        use_engine("tesseract")
    else:
        raise

Prevention

When it happens

Trigger: settings.docling.langs containing a code absent from LANG_TO_RAPIDOCR while ocr_model is 'rapidocr' — most often a language RapidOCR does not support (its set is small: mainly chinese/english and a few others) or a code in the wrong format.

Common situations: Choosing rapidocr for CPU efficiency and then requesting European languages it does not cover; carrying over a langs list written for easyocr/tesseract; assuming RapidOCR's language breadth matches Tesseract's.

Related errors


AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15). Data as JSON: /api/errors/c31a1062285c45d7. Report an issue: GitHub.