{"record":{"id":"40c89fbc3dc2394f","repo":"PaddlePaddle/PaddleOCR","slug":"unknown-or-missing-job-state-state","errorCode":null,"errorMessage":"Unknown or missing job state: {state}","messagePattern":"Unknown or missing job state: (.+?)","errorType":"exception","errorClass":"ResponseFormatError","httpStatus":null,"severity":"error","filePath":"paddleocr/_api_client/_core.py","lineNumber":122,"sourceCode":"\n\ndef extract_api_message_from_payload(payload: dict) -> Optional[str]:\n    for key in (\"msg\", \"errorMsg\", \"message\"):\n        value = payload.get(key)\n        if value:\n            return str(value)\n    data = payload.get(\"data\")\n    if isinstance(data, dict):\n        value = data.get(\"errorMsg\")\n        if value:\n            return str(value)\n    return None\n\n\ndef validate_state(data: dict) -> str:\n    state = data.get(\"state\")\n    if state not in {\"pending\", \"running\", \"done\", \"failed\"}:\n        raise ResponseFormatError(f\"Unknown or missing job state: {state}\")\n    return state\n\n\ndef job_status_from_data(job_id: str, data: dict) -> JobStatus:\n    state = validate_state(data)\n    progress = None\n    ep = data.get(\"extractProgress\")\n    if ep:\n        if not isinstance(ep, dict):\n            raise ResponseFormatError(\"'extractProgress' must be an object.\")\n        progress = Progress(\n            total_pages=ep.get(\"totalPages\", 0),\n            extracted_pages=ep.get(\"extractedPages\", 0),\n            start_time=ep.get(\"startTime\"),\n            end_time=ep.get(\"endTime\"),\n        )\n    return JobStatus(\n        job_id=job_id,","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/paddleocr/_api_client/_core.py#L104-L140","documentation":"Raised as ResponseFormatError by validate_state() when the job-status payload's 'state' field is missing or outside {pending, running, done, failed}. It signals an unexpected response body from the service, not a job failure.","triggerScenarios":"Any status poll (wait loop, get_status) where data.get('state') is None, a new state string introduced server-side, or a payload that is not the expected job-status dict (e.g. an error envelope).","commonSituations":"Service API version drift adding new states, gateway/HTML error pages parsed as JSON, or unwrapped payloads where the data envelope changed.","solutions":["Log the raw response body to see what 'state' actually contained.","Upgrade the paddleocr package to a version matching the current service API.","If a proxy/gateway intercepts responses, bypass it or fix its error format.","Retry the status call once; a transient malformed response can occur under load."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"from paddleocr._api_client.errors import ResponseFormatError\ntry:\n    status = await client.get_status(job_id)\nexcept ResponseFormatError as e:\n    log.error(\"unexpected status payload: %s\", e)\n    # one retry, then surface; likely version drift or gateway interference","preventionTips":["Keep the package version in sync with the service API.","Log raw response bodies when ResponseFormatError occurs to diagnose drift."],"tags":["response-format","api","parsing"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}