{"record":{"id":"c1de20786c58e889","repo":"PaddlePaddle/PaddleOCR","slug":"destination","errorCode":null,"errorMessage":"{destination}","messagePattern":"\\{destination\\}","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"paddleocr/_api_client/_resources.py","lineNumber":145,"sourceCode":"        _validate_result_resource_filename(filename)\n        target = destination_path / filename\n    elif destination_path.exists() and destination_path.is_dir():\n        target = destination_path / _safe_url_basename(url_path)\n    else:\n        target = destination_path\n\n    parent = target.parent\n    if not parent.exists():\n        raise FileNotFoundError(str(parent))\n    if not parent.is_dir():\n        raise InvalidRequestError(f\"Destination parent must be a directory: {parent}\")\n    return target\n\n\ndef _require_existing_directory(destination: str) -> Path:\n    dest_dir = Path(destination)\n    if not dest_dir.exists():\n        raise FileNotFoundError(destination)\n    if not dest_dir.is_dir():\n        raise InvalidRequestError(\n            f\"Destination must be an existing directory: {destination}\"\n        )\n    return dest_dir\n\n\ndef _require_writable_target(target: Path, overwrite: bool) -> None:\n    if target.exists() and not overwrite:\n        raise InvalidRequestError(f\"Destination already exists: {target}\")\n\n\ndef _atomic_write(target: Path, content: bytes, overwrite: bool) -> None:\n    fd, temp_path = tempfile.mkstemp(\n        prefix=f\".{target.name}.tmp-\",\n        dir=str(target.parent),\n    )\n    try:","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/paddleocr/_api_client/_resources.py#L127-L163","documentation":"Builtin FileNotFoundError raised by _require_existing_directory when the destination passed to save_ocr_result_resources / save_document_parsing_result_resources does not exist on disk. Unlike save_resource, the batch helpers require destination to be an existing directory and never create it.","triggerScenarios":"save_ocr_result_resources(result, '/data/out') with /data/out absent; output directory referenced in config but never created in this environment/deployment.","commonSituations":"Fresh clone/container where the output dir is expected to pre-exist; CI runs with a workspace that lacks the artifacts dir; directory name typo; the dir exists on the dev machine but not in production mount layout.","solutions":["Create the directory before the call: Path(dest).mkdir(parents=True, exist_ok=True)","Verify the path against the actual mount layout in the failing environment (container volume, network share)","Add a startup check that creates/validates configured output directories once, not per-file"],"exampleFix":"# before\nsave_ocr_result_resources(result, '/data/out')  # dir missing\n\n# after\nfrom pathlib import Path\nPath('/data/out').mkdir(parents=True, exist_ok=True)\nsave_ocr_result_resources(result, '/data/out')","handlingStrategy":"validation","validationCode":"from pathlib import Path\nPath(destination).mkdir(parents=True, exist_ok=True)\nassert Path(destination).is_dir()","typeGuard":null,"tryCatchPattern":"try:\n    save_ocr_result_resources(result, dest_dir)\nexcept FileNotFoundError as e:\n    Path(str(e)).mkdir(parents=True, exist_ok=True)\n    save_ocr_result_resources(result, dest_dir)","preventionTips":["Pre-create output directories once at startup","The batch helpers never create directories — treat that as a contract"],"tags":["filesystem","directory","download"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}