{"record":{"id":"e5577505d9b9ae53","repo":"PaddlePaddle/PaddleOCR","slug":"job-model-is-not-an-ocr-model-job-model","errorCode":null,"errorMessage":"Job model is not an OCR model: {job.model}.","messagePattern":"Job model is not an OCR model: (.+?)\\.","errorType":"validation","errorClass":"InvalidRequestError","httpStatus":null,"severity":"error","filePath":"paddleocr/_api_client/_core.py","lineNumber":98,"sourceCode":"        ):\n            raise InvalidRequestError(\"PP-StructureV3 requires PPStructureV3Options.\")\n        if is_vl_model(model) and not isinstance(options, PaddleOCRVLOptions):\n            raise InvalidRequestError(\"PaddleOCR-VL models require PaddleOCRVLOptions.\")\n        return options\n    if model == Model.PP_STRUCTURE_V3:\n        return PPStructureV3Options()\n    return PaddleOCRVLOptions()\n\n\ndef job_id_for_task(job: Union[Job, str], task: str) -> str:\n    if isinstance(job, str):\n        return job\n    if job.task != task:\n        raise InvalidRequestError(\n            f\"Job task mismatch: expected {task}, got {job.task}.\"\n        )\n    if task == \"ocr\" and not is_ocr_model(job.model):\n        raise InvalidRequestError(f\"Job model is not an OCR model: {job.model}.\")\n    if task == \"document_parsing\" and not is_document_parsing_model(job.model):\n        raise InvalidRequestError(\n            f\"Job model is not a document parsing model: {job.model}.\"\n        )\n    return job.job_id\n\n\ndef extract_api_message_from_payload(payload: dict) -> Optional[str]:\n    for key in (\"msg\", \"errorMsg\", \"message\"):\n        value = payload.get(key)\n        if value:\n            return str(value)\n    data = payload.get(\"data\")\n    if isinstance(data, dict):\n        value = data.get(\"errorMsg\")\n        if value:\n            return str(value)\n    return None","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/paddleocr/_api_client/_core.py#L80-L116","documentation":"Raised as InvalidRequestError by job_id_for_task() when task == 'ocr' but the Job's model fails is_ocr_model(). It catches Jobs that claim the OCR task while carrying a non-OCR model, before an OCR endpoint is called with an incompatible job id.","triggerScenarios":"Passing a Job whose model is a document-parsing or VL model to an OCR-scoped method (task='ocr').","commonSituations":"Hand-constructed or deserialized Job objects with inconsistent task/model fields, or jobs from an older version where task semantics differed.","solutions":["Use the Job returned by the matching create call; do not synthesize Job objects manually.","Verify job.model is an OCR model before calling OCR follow-up methods.","If the job is genuinely document parsing, use the document-parsing endpoint."],"exampleFix":"# before\nocr_result = client.get_ocr_result(job)  # job.model is PP-StructureV3\n\n# after\nassert is_ocr_model(job.model), \"use document-parsing result API for this job\"\nocr_result = client.get_ocr_result(job)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"from paddleocr._api_client.models import is_ocr_model\n\ndef job_is_ocr(job) -> bool:\n    return job.task == \"ocr\" and is_ocr_model(job.model)","tryCatchPattern":null,"preventionTips":["Only pass Job objects returned by the corresponding create call.","Validate deserialized Jobs before use."],"tags":["validation","job","model","client-side"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}