{"record":{"id":"c0cc05e64ba52309","repo":"PaddlePaddle/PaddleOCR","slug":"job-job-id-failed-error-msg-c0cc05","errorCode":null,"errorMessage":"Job {job_id} failed: {error_msg}","messagePattern":"Job (.+?) failed: (.+?)","errorType":"exception","errorClass":"JobFailedError","httpStatus":null,"severity":"error","filePath":"paddleocr/_api_client/_poller.py","lineNumber":79,"sourceCode":"        start = time.monotonic()\n        deadline = start + self._max_wait_time\n\n        while True:\n            now = time.monotonic()\n            if now >= deadline:\n                raise PollTimeoutError(job_id, now - start)\n\n            data = self._http.get_job_status(job_id)\n            state = validate_state(data)\n\n            if state == \"done\":\n                json_url = validate_result_json_url(data)\n                jsonl_data = self._http.fetch_jsonl(json_url)\n                return jsonl_data, data\n\n            if state == \"failed\":\n                error_msg = data.get(\"errorMsg\", \"Unknown error\")\n                raise JobFailedError(job_id, error_msg)\n\n            remaining = deadline - time.monotonic()\n            if remaining <= 0:\n                raise PollTimeoutError(job_id, time.monotonic() - start)\n\n            time.sleep(min(interval, remaining))\n            interval = min(interval * self._multiplier, self._max_interval)\n\n    def get_status(self, job_id: str) -> JobStatus:\n        data = self._http.get_job_status(job_id)\n        return job_status_from_data(job_id, data)\n\n    def get_batch_status(self, batch_id: str) -> BatchStatus:\n        data = self._http.get_batch_status(batch_id)\n        return parse_batch_status(batch_id, data)\n\n\ndef parse_ocr_result(job_id: str, jsonl_data: list) -> OCRResult:","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/paddleocr/_api_client/_poller.py#L61-L97","documentation":"JobFailedError raised when the job status payload reports state == 'failed'. The server-side pipeline rejected or crashed on the job; the message embeds the job_id and the server's errorMsg field (or 'Unknown error' if the payload omitted errorMsg). This is a terminal state — no amount of continued polling will change it.","triggerScenarios":"poll_until_done() observes state 'failed' for a submitted OCR/document-parsing job. Typical server reasons: unsupported or corrupt input file, file larger than the server limit, OCR backend crash, invalid parameters stored with the job, or quota/billing rejection.","commonSituations":"Uploading a password-protected or zero-byte PDF; sending an image format the server cannot decode; server OOM during inference on very large pages; API plan limits exceeded; server version regression marking jobs failed intermittently.","solutions":["Read the errorMsg embedded in the exception — it comes straight from the server and names the root cause","Reproduce with the smallest input that fails; if a specific file always fails, validate/re-save that file (e.g. re-export the PDF) before resubmitting","If errorMsg is 'Unknown error', call get_status(job_id) to inspect the full raw status payload for extra fields","If failures are intermittent or input-independent, check server logs/capacity rather than the client"],"exampleFix":"# before\njsonl, raw = poller.poll_until_done(job_id)  # JobFailedError bubbles up raw\n\n# after\ntry:\n    jsonl, raw = poller.poll_until_done(job_id)\nexcept JobFailedError as e:\n    status = poller.get_status(job_id)\n    logger.error(\"job %s failed: %s raw=%s\", e.job_id, e, status.raw)","handlingStrategy":"try-catch","validationCode":"# validate input before submitting to reduce server-side failures\ndef submittable(path) -> bool:\n    return path.stat().st_size > 0 and path.suffix.lower() in {'.pdf', '.png', '.jpg', '.jpeg', '.bmp', '.tiff'}","typeGuard":null,"tryCatchPattern":"from paddleocr._api_client.errors import JobFailedError\ntry:\n    jsonl, raw = poller.poll_until_done(job_id)\nexcept JobFailedError as e:\n    logger.error(\"server failed job %s: %s\", e.job_id, e)\n    raise","preventionTips":["Pre-check files: non-zero size, supported format, not password-protected PDFs","Keep the job_id and resubmit only the failed job, not the whole batch","Record errorMsg strings to spot recurring server-side causes"],"tags":["async-jobs","server-error","polling"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}