{"record":{"id":"4deb0886f613e99c","repo":"PaddlePaddle/PaddleOCR","slug":"ocr-result-is-required","errorCode":null,"errorMessage":"OCR result is required.","messagePattern":"OCR result is required\\.","errorType":"exception","errorClass":"InvalidRequestError","httpStatus":null,"severity":"warning","filePath":"paddleocr/_api_client/_resources.py","lineNumber":71,"sourceCode":"\n    try:\n        response.raise_for_status()\n    except requests.RequestException as e:\n        raise NetworkError(f\"Failed to download resource: {e}\") from e\n\n    _atomic_write(target, response.content, overwrite)\n    return str(target)\n\n\ndef save_ocr_result_resources(\n    result: OCRResult,\n    destination: str,\n    *,\n    overwrite: bool = False,\n    timeout: float = 300.0,\n) -> List[str]:\n    if result is None:\n        raise InvalidRequestError(\"OCR result is required.\")\n    dest_dir = _require_existing_directory(destination)\n    saved_paths = []\n    for index, page in enumerate(result.pages):\n        if not page.ocr_image_url:\n            continue\n        filename = f\"ocr-page-{index + 1}{_safe_resource_extension(page.ocr_image_url)}\"\n        saved_paths.append(\n            save_resource(\n                page.ocr_image_url,\n                str(dest_dir / filename),\n                overwrite=overwrite,\n                timeout=timeout,\n            )\n        )\n    return saved_paths\n\n\ndef save_document_parsing_result_resources(","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/paddleocr/_api_client/_resources.py#L53-L89","documentation":"InvalidRequestError raised by save_ocr_result_resources when its result argument is None. Client-side guard before any directory check or download — the OCRResult object itself is the missing input.","triggerScenarios":"Calling save_ocr_result_resources(None, dest), typically because a variable holding the OCRResult was assigned on a branch that did not run (e.g. an error path left it None) or a refactor changed the function's return shape.","commonSituations":"Result assigned inside try/except and used after the except block; helper returns None on failure and caller forgets to check; passing the raw JSONL instead of the parsed OCRResult object.","solutions":["Ensure you pass a parsed OCRResult from the OCR flow (poll + parse), not None and not the raw payload","Check for None at the call site and surface a clearer error with context about which step failed","If a helper can legitimately return None, branch on it before calling this function"],"exampleFix":"# before\nsave_ocr_result_resources(maybe_result, dest)  # maybe_result is None on error path\n\n# after\nif result is None:\n    raise RuntimeError(\"OCR job produced no result; check job status\")\nsave_ocr_result_resources(result, dest)","handlingStrategy":"validation","validationCode":"if result is None or not getattr(result, 'pages', None):\n    raise RuntimeError('no OCR result to save; check job status first')","typeGuard":"from paddleocr._api_client.results import OCRResult\ndef is_ocr_result(o) -> bool:\n    return isinstance(o, OCRResult) and hasattr(o, 'pages')","tryCatchPattern":"try:\n    save_ocr_result_resources(result, dest_dir)\nexcept InvalidRequestError as e:\n    raise RuntimeError(f'OCR pipeline produced no result: {e}') from e","preventionTips":["Assign results in a single code path; never use a variable an except branch may have skipped","Check job outcome before attempting to save resources"],"tags":["validation","arguments","ocr"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}