{"record":{"id":"72de8fd87c7cbb59","repo":"PaddlePaddle/PaddleOCR","slug":"pp-structurev3-requires-ppstructurev3options","errorCode":null,"errorMessage":"PP-StructureV3 requires PPStructureV3Options.","messagePattern":"PP-StructureV3 requires PPStructureV3Options\\.","errorType":"validation","errorClass":"InvalidRequestError","httpStatus":null,"severity":"error","filePath":"paddleocr/_api_client/_core.py","lineNumber":81,"sourceCode":"\n\ndef resolve_model(model: Union[Model, str]) -> Model:\n    if isinstance(model, Model):\n        return model\n    try:\n        return Model(model)\n    except ValueError as e:\n        raise InvalidRequestError(f\"Unsupported model: {model}\") from e\n\n\ndef resolve_document_options(\n    model: Model, options: Optional[DocParsingOptions]\n) -> DocParsingOptions:\n    if options is not None:\n        if model == Model.PP_STRUCTURE_V3 and not isinstance(\n            options, PPStructureV3Options\n        ):\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):","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/paddleocr/_api_client/_core.py#L63-L99","documentation":"Raised as InvalidRequestError by resolve_document_options() when the model is PP-StructureV3 but the supplied options object is not a PPStructureV3Options instance. Each document-parsing model has its own options type; the mismatch is rejected client-side so the request payload is built correctly.","triggerScenarios":"Calling document parsing with model=Model.PP_STRUCTURE_V3 (or its string) and options=PaddleOCRVLOptions(...) or any other DocParsingOptions subclass.","commonSituations":"Sharing one options object across models to reduce config duplication, or upgrading from a VL model to PP-StructureV3 without changing the options class.","solutions":["Construct PPStructureV3Options() for PP-StructureV3 jobs.","Or omit options entirely; resolve_document_options defaults to PPStructureV3Options() for this model.","Map each model to its options class in your config layer."],"exampleFix":"# before\njob = client.parse_document(file_path=\"a.pdf\", model=\"PP-StructureV3\", options=PaddleOCRVLOptions())\n\n# after\nfrom paddleocr._api_client.options import PPStructureV3Options\njob = client.parse_document(file_path=\"a.pdf\", model=\"PP-StructureV3\", options=PPStructureV3Options())","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"from paddleocr._api_client.models import Model\nfrom paddleocr._api_client.options import PPStructureV3Options\n\ndef options_match(model, options) -> bool:\n    if model == Model.PP_STRUCTURE_V3:\n        return isinstance(options, PPStructureV3Options)\n    return True","tryCatchPattern":null,"preventionTips":["Map each model to its options class in one factory function.","Pass options=None to accept the correct default instead of guessing."],"tags":["validation","options","model","client-side"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}