PaddlePaddle/PaddleOCR · error · InvalidRequestError

PP-StructureV3 requires PPStructureV3Options.

Error message

PP-StructureV3 requires PPStructureV3Options.

What it means

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.

Source

Thrown at paddleocr/_api_client/_core.py:81


def resolve_model(model: Union[Model, str]) -> Model:
    if isinstance(model, Model):
        return model
    try:
        return Model(model)
    except ValueError as e:
        raise InvalidRequestError(f"Unsupported model: {model}") from e


def resolve_document_options(
    model: Model, options: Optional[DocParsingOptions]
) -> DocParsingOptions:
    if options is not None:
        if model == Model.PP_STRUCTURE_V3 and not isinstance(
            options, PPStructureV3Options
        ):
            raise InvalidRequestError("PP-StructureV3 requires PPStructureV3Options.")
        if is_vl_model(model) and not isinstance(options, PaddleOCRVLOptions):
            raise InvalidRequestError("PaddleOCR-VL models require PaddleOCRVLOptions.")
        return options
    if model == Model.PP_STRUCTURE_V3:
        return PPStructureV3Options()
    return PaddleOCRVLOptions()


def job_id_for_task(job: Union[Job, str], task: str) -> str:
    if isinstance(job, str):
        return job
    if job.task != task:
        raise InvalidRequestError(
            f"Job task mismatch: expected {task}, got {job.task}."
        )
    if task == "ocr" and not is_ocr_model(job.model):
        raise InvalidRequestError(f"Job model is not an OCR model: {job.model}.")
    if task == "document_parsing" and not is_document_parsing_model(job.model):

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Construct PPStructureV3Options() for PP-StructureV3 jobs.
  2. Or omit options entirely; resolve_document_options defaults to PPStructureV3Options() for this model.
  3. Map each model to its options class in your config layer.

Example fix

# before
job = client.parse_document(file_path="a.pdf", model="PP-StructureV3", options=PaddleOCRVLOptions())

# after
from paddleocr._api_client.options import PPStructureV3Options
job = client.parse_document(file_path="a.pdf", model="PP-StructureV3", options=PPStructureV3Options())
Defensive patterns

Strategy: type-guard

Type guard

from paddleocr._api_client.models import Model
from paddleocr._api_client.options import PPStructureV3Options

def options_match(model, options) -> bool:
    if model == Model.PP_STRUCTURE_V3:
        return isinstance(options, PPStructureV3Options)
    return True

Prevention

When it happens

Trigger: Calling document parsing with model=Model.PP_STRUCTURE_V3 (or its string) and options=PaddleOCRVLOptions(...) or any other DocParsingOptions subclass.

Common situations: Sharing one options object across models to reduce config duplication, or upgrading from a VL model to PP-StructureV3 without changing the options class.

Related errors


AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14). Data as JSON: /api/errors/72de8fd87c7cbb59. Report an issue: GitHub.