PaddlePaddle/PaddleOCR · error · JobFailedError
Job {job_id} failed: {error_msg}
Error message
Job {job_id} failed: {error_msg} What it means
Raised as JobFailedError by the async poller when a submitted job's state transitions to 'failed' on the service side. The message embeds the job_id and the service-provided errorMsg (or 'Unknown error' when the payload omits it). This means the request was accepted but processing failed downstream, so retrying with identical inputs often fails again.
Source
Thrown at paddleocr/_api_client/_async_poller.py:72
start = loop.time()
deadline = start + self._max_wait_time
while True:
now = loop.time()
if now >= deadline:
raise PollTimeoutError(job_id, now - start)
data = await self._http.get_job_status(job_id)
state = validate_state(data)
if state == "done":
json_url = validate_result_json_url(data)
jsonl_data = await self._http.fetch_jsonl(json_url)
return jsonl_data, data
if state == "failed":
error_msg = data.get("errorMsg", "Unknown error")
raise JobFailedError(job_id, error_msg)
remaining = deadline - loop.time()
if remaining <= 0:
raise PollTimeoutError(job_id, loop.time() - start)
await asyncio.sleep(min(interval, remaining))
interval = min(interval * self._multiplier, self._max_interval)
async def get_status(self, job_id: str) -> JobStatus:
data = await self._http.get_job_status(job_id)
return job_status_from_data(job_id, data)
async def get_batch_status(self, batch_id: str) -> BatchStatus:
data = await self._http.get_batch_status(batch_id)
return parse_batch_status(batch_id, data)
View on GitHub (pinned to 2661c7c0ef)
Solutions
- Read the errorMsg embedded in the exception to identify the service-side reason before changing anything.
- Verify the input file: open the file_url/file_path locally, confirm it is a supported format and not truncated.
- Check that the model and options match the input (e.g. document-parsing model for PDFs, OCR model for images).
- Retry once with a fresh job after fixing the input; if errorMsg indicates a transient internal error, recreate the job with the same input.
- If failures persist, capture job_id and errorMsg and report to PaddleOCR AI Studio support.
Example fix
// before
result = await client.ocr(file_path="doc.pdf") # raises JobFailedError
// after
try:
result = await client.ocr(file_path="doc.pdf")
except JobFailedError as e:
print(f"job {e.job_id} failed: {e.message}")
# inspect input file / model choice, then resubmit Defensive patterns
Strategy: try-catch
Try / catch
from paddleocr._api_client.errors import JobFailedError
try:
result = await client.ocr(file_path=path)
except JobFailedError as e:
# e.job_id and str(e) carry the service-side reason
log.warning("job %s failed: %s", e.job_id, e)
raise Prevention
- Validate the file opens and is a supported format before submitting.
- Match the model to the input type (OCR for images, document parsing for PDFs).
- Log errorMsg from every JobFailedError to catch recurring input problems.
When it happens
Trigger: Calling an async API method that polls to completion (e.g. create OCR/document-parsing job then wait) where get_job_status() eventually returns state == 'failed'. The payload's errorMsg field supplies the reason; if absent, 'Unknown error' is used.
Common situations: Corrupt or unreadable input file at the given file_url, unsupported file format or oversized document, model mismatch for the input type, or transient service-side failures during extraction. Also seen when the uploaded URL expires before the service fetches it.
Related errors
- Model ${model} is not a document parsing model.
- resourceUrl is required.
- Destination already exists: ${target}
- Job ${jobId} failed: ${errorMsg}
- Timed out after ${timeoutMs}ms waiting for job ${jobId}
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/dd89a7be8eada5ff.
Report an issue: GitHub.