{"record":{"id":"29231649c6d7c09e","repo":"PaddlePaddle/PaddleOCR","slug":"file-path","errorCode":null,"errorMessage":"{file_path}","messagePattern":"\\{file_path\\}","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"paddleocr/_api_client/_async_http.py","lineNumber":117,"sourceCode":"        async with self._session.post(\n            self._jobs_url,\n            json=body,\n            headers={\"Content-Type\": \"application/json\"},\n        ) as resp:\n            await self._raise_for_response(resp)\n            data = await self._response_data(resp)\n            return extract_job_id(data)\n\n    async def submit_file(\n        self,\n        model: str,\n        file_path: str,\n        optional_payload: dict,\n        page_ranges: Optional[str] = None,\n        batch_id: Optional[str] = None,\n    ) -> str:\n        if not os.path.exists(file_path):\n            raise FileNotFoundError(file_path)\n\n        form = aiohttp.FormData()\n        form.add_field(\"model\", model)\n        form.add_field(\"optionalPayload\", json.dumps(optional_payload))\n        if page_ranges is not None:\n            form.add_field(\"pageRanges\", page_ranges)\n        if batch_id is not None:\n            form.add_field(\"batchId\", batch_id)\n\n        with open(file_path, \"rb\") as f:\n            file_data = f.read()\n        form.add_field(\n            \"file\",\n            file_data,\n            filename=os.path.basename(file_path),\n        )\n\n        await self._ensure_session()","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/paddleocr/_api_client/_async_http.py#L99-L135","documentation":"FileNotFoundError from submit_file in the async API client when os.path.exists(file_path) is false before uploading. The check runs synchronously before building the aiohttp multipart form, so a bad local path fails fast rather than as a network error.","triggerScenarios":"Calling the async document-parsing client's file submission with a relative path from a different cwd; the file deleted/moved between queueing and submission; a directory (exists but read fails later) or plain typo in the path string.","commonSituations":"Async pipelines where the path was computed in another task/worker with a different cwd; temp files cleaned up by the time the upload coroutine runs.","solutions":["Pass an absolute path: `str(Path(file_path).resolve())` at submission time.","Verify with os.path.isfile (not just exists) before submitting.","For files that may vanish, read bytes earlier or hold the file open until the upload starts."],"exampleFix":"// before\njob = await http.submit_file(model, \"./tmp/scan.pdf\", {})\n\n// after\nfrom pathlib import Path\njob = await http.submit_file(model, str(Path(\"./tmp/scan.pdf\").resolve()), {})","handlingStrategy":"validation","validationCode":"import os\n\ndef submittable_file(file_path: str) -> bool:\n    return os.path.isfile(file_path)","typeGuard":"from pathlib import Path\n\ndef is_existing_file(value: object) -> bool:\n    return isinstance(value, (str, os.PathLike)) and Path(value).is_file()","tryCatchPattern":"try:\n    job_id = await http.submit_file(model, file_path, payload)\nexcept FileNotFoundError:\n    file_path = str(Path(file_path).resolve())\n    if not Path(file_path).is_file():\n        raise\n    job_id = await http.submit_file(model, file_path, payload)","preventionTips":["Resolve to absolute paths at submission time, especially in async workers with shifting cwd.","Keep temp files alive (delay cleanup) until the upload coroutine has started.","Check isfile (not just exists) to catch directories early."],"tags":["python","asyncio","file-not-found","upload","api-client"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}