PaddlePaddle/PaddleOCR · error · InvalidRequestError
Job task mismatch: expected {task}, got {job.task}.
Error message
Job task mismatch: expected {task}, got {job.task}. What it means
Raised as InvalidRequestError by job_id_for_task() when a Job object is passed to a task-scoped method (e.g. result fetching for 'ocr') but the job's task attribute differs. This prevents, for example, feeding a document-parsing job into an OCR result endpoint.
Source
Thrown at paddleocr/_api_client/_core.py:94
) -> 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):
raise InvalidRequestError(
f"Job model is not a document parsing model: {job.model}."
)
return job.job_id
def extract_api_message_from_payload(payload: dict) -> Optional[str]:
for key in ("msg", "errorMsg", "message"):
value = payload.get(key)
if value:
return str(value)
data = payload.get("data")
if isinstance(data, dict):View on GitHub (pinned to 2661c7c0ef)
Solutions
- Route each Job to the follow-up method matching its task.
- Check job.task before dispatching, or just pass the job_id string if you know the endpoint.
- Keep OCR and document-parsing jobs in separate variables/queues.
Example fix
# before
ocr_result = await client.get_ocr_result(doc_job) # doc_job.task == 'document_parsing'
# after
if doc_job.task == "document_parsing":
result = await client.get_document_parsing_result(doc_job) Defensive patterns
Strategy: type-guard
Validate before calling
def route_job(job, ocr_fn, doc_fn):
return ocr_fn(job) if job.task == "ocr" else doc_fn(job) Type guard
def is_task(job, task: str) -> bool:
return job.task == task Prevention
- Store the task name with the job id when persisting.
- Never share one 'current job' variable between OCR and document-parsing flows.
When it happens
Trigger: Passing a Job returned from a document-parsing create call to an OCR-specific method (or vice versa); the job.task string does not equal the method's expected task name.
Common situations: Mixed pipelines handling both OCR and document parsing that share one variable for 'current job', or copy-pasted follow-up calls after switching endpoint.
Related errors
- Job model is not an OCR model: {job.model}.
- Job model is not a document parsing model: {job.model}.
- fileUrl and filePath are mutually exclusive.
- Either file_url or file_path is required.
- file_url and file_path are mutually exclusive.
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/c5c6e0970abd34d9.
Report an issue: GitHub.