{"record":{"id":"e90da8e0aa77227f","repo":"PaddlePaddle/PaddleOCR","slug":"extractprogress-must-be-an-object","errorCode":null,"errorMessage":"'extractProgress' must be an object.","messagePattern":"'extractProgress' must be an object\\.","errorType":"exception","errorClass":"ResponseFormatError","httpStatus":null,"severity":"error","filePath":"paddleocr/_api_client/_core.py","lineNumber":132,"sourceCode":"        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,\n        state=state,\n        progress=progress,\n        result=data.get(\"resultUrl\"),\n        error_msg=data.get(\"errorMsg\"),\n    )\n\n\ndef raise_for_status(status_code: int, msg: str) -> None:\n    if 200 <= status_code < 300:\n        return","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/paddleocr/_api_client/_core.py#L114-L150","documentation":"Raised as ResponseFormatError by job_status_from_data() when the payload's 'extractProgress' field is truthy but not a JSON object (dict). The progress parser expects totalPages/extractedPages/startTime/endTime keys inside an object; any other shape aborts status parsing.","triggerScenarios":"get_status() or the poll loop receiving a status payload where extractProgress is a string, number, or list (e.g. a bare percentage integer).","commonSituations":"Service API changes that flatten or retype progress fields, or mock/test servers returning simplified payloads.","solutions":["Log the raw status payload to inspect the actual extractProgress value.","Update the package to match the service's response schema version.","Fix test doubles to return an object with totalPages/extractedPages/startTime/endTime.","Report the schema change if the live service sends a non-object progress field."],"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    if \"extractProgress\" in str(e):\n        log.error(\"progress shape changed; raw payload needed\")\n        raise","preventionTips":["Mock servers must replicate the documented extractProgress object shape.","Pin the package version against a known service schema."],"tags":["response-format","api","parsing","progress"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}