{"record":{"id":"fd63a1c7859dadf1","repo":"docling-project/docling","slug":"invalid-rapidocr-model-spec-value-r-expected","errorCode":null,"errorMessage":"Invalid RapidOCR model spec {value!r}. Expected '<backend>:<lang>', e.g. 'onnxruntime:th'.","messagePattern":"Invalid RapidOCR model spec (.+?)\\. Expected '<backend>:<lang>', e\\.g\\. 'onnxruntime:th'\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"docling/models/stages/ocr/rapid_ocr_model.py","lineNumber":107,"sourceCode":"    # Language exactly as the user wrote it\n    user_lang: str | None = None\n\n    # Language code the rapidocr registry expects, after normalization and aliasing.\n    rapidocr_lang_token: str | None = None\n\n    # PP-OCR backbone that the (backend, language) pair resolves to.\n    ppocr_version: \"OCRVersion | None\" = None\n\n\ndef _parse_rapidocr_model_spec(value: str) -> _RapidOcrModelSpec:\n    \"\"\"Parse a `<backend>:<lang>` prefetch spec into its requested form.\n\n    The pair is routed through _resolve_rapidocr so the prefetcher can never accept a\n    combination the runtime would reject, but only the user's own values are kept.\n    \"\"\"\n    backend, separator, lang = value.partition(\":\")\n    if not separator or not backend or not lang or \":\" in lang:\n        raise ValueError(\n            f\"Invalid RapidOCR model spec {value!r}. \"\n            \"Expected '<backend>:<lang>', e.g. 'onnxruntime:th'.\"\n        )\n    if backend not in _RAPIDOCR_BACKENDS:\n        raise ValueError(\n            f\"Unknown RapidOCR backend {backend!r} in {value!r}. \"\n            f\"Supported: {list(_RAPIDOCR_BACKENDS)}.\"\n        )\n    try:\n        _resolve_rapidocr(lang, backend)\n    except ValueError as err:\n        raise ValueError(f\"Invalid RapidOCR model spec {value!r}: {err}\") from err\n    return _RapidOcrModelSpec(backend=backend, user_lang=lang)\n\n\ndef _backend_to_engine_type(backend: str) -> \"EngineType\":\n    \"\"\"Map a docling backend name onto the rapidocr EngineType it stands for.\"\"\"\n    from rapidocr.utils.typings import EngineType","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/models/stages/ocr/rapid_ocr_model.py#L89-L125","documentation":"RapidOCR model prefetching accepts specs of the exact form '<backend>:<lang>' (e.g. 'onnxruntime:th'). _parse_rapidocr_model_spec splits on ':' and raises ValueError for the whole spec string when it is malformed: missing separator, empty backend, empty language, or a second ':' in the language part. The error quotes the offending value and shows the expected shape.","triggerScenarios":"Configuring RapidOCR prefetch model specs with values like 'onnxruntime' (no colon), ':th', 'onnxruntime:', or 'onnxruntime:th:extra' — the partition/validation in the parser fails.","commonSituations":"Hand-written YAML/JSON pipeline configs with typos; env-var-driven specs concatenated incorrectly; whitespace-only segments after trimming.","solutions":["Format every spec as exactly '<backend>:<lang>', e.g. 'onnxruntime:th' or 'openvino:en'.","Validate specs at config-load time with the same partition(':') check before passing them to docling.","Use one of the known backends (see _RAPIDOCR_BACKENDS: onnxruntime, openvino, paddle, torch) and a supported language code."],"exampleFix":"# before\nmodels = [\"onnxruntime-th\", \"onnxruntime:th:ch\"]  # wrong separators -> ValueError\n\n# after\nmodels = [\"onnxruntime:th\", \"openvino:en\"]","handlingStrategy":"validation","validationCode":"import re\n\nSPEC_RE = re.compile(r\"^(onnxruntime|openvino|paddle|torch):[^:]+$\")\n\ndef valid_rapidocr_spec(spec: str) -> bool:\n    return bool(SPEC_RE.match(spec))\n\nspecs = [s for s in configs[\"models\"] if valid_rapidocr_spec(s)]","typeGuard":"def is_valid_rapidocr_spec(value: str) -> bool:\n    backend, sep, lang = value.partition(\":\")\n    return bool(sep and backend and lang and \":\" not in lang)","tryCatchPattern":"try:\n    specs = [_parse_rapidocr_model_spec(s) for s in raw_specs]\nexcept ValueError as err:\n    raise ConfigError(f\"Bad RapidOCR model config: {err}\") from err","preventionTips":["Validate '<backend>:<lang>' shape at config load, not at pipeline build.","Document the spec grammar next to the config knob.","Reject specs with more than one colon early in your own tooling."],"tags":["rapidocr","ocr","configuration","validation"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}