PaddlePaddle/PaddleOCR · warning · InvalidRequestError
Destination must be an existing directory: {destination}
Error message
Destination must be an existing directory: {destination} What it means
InvalidRequestError raised by _require_existing_directory when the destination exists but is not a directory (a regular file, broken behavior for the batch helpers). The batch save functions iterate pages and write multiple files, so destination must be a directory that already exists.
Source
Thrown at paddleocr/_api_client/_resources.py:147
elif destination_path.exists() and destination_path.is_dir():
target = destination_path / _safe_url_basename(url_path)
else:
target = destination_path
parent = target.parent
if not parent.exists():
raise FileNotFoundError(str(parent))
if not parent.is_dir():
raise InvalidRequestError(f"Destination parent must be a directory: {parent}")
return target
def _require_existing_directory(destination: str) -> Path:
dest_dir = Path(destination)
if not dest_dir.exists():
raise FileNotFoundError(destination)
if not dest_dir.is_dir():
raise InvalidRequestError(
f"Destination must be an existing directory: {destination}"
)
return dest_dir
def _require_writable_target(target: Path, overwrite: bool) -> None:
if target.exists() and not overwrite:
raise InvalidRequestError(f"Destination already exists: {target}")
def _atomic_write(target: Path, content: bytes, overwrite: bool) -> None:
fd, temp_path = tempfile.mkstemp(
prefix=f".{target.name}.tmp-",
dir=str(target.parent),
)
try:
with os.fdopen(fd, "wb") as temp_file:
temp_file.write(content)View on GitHub (pinned to 2661c7c0ef)
Solutions
- Pass the directory, not a file path, to the batch helpers
- If a file occupies the name, move/remove it and create a real directory there
- Use a consistent convention: directories end with the output dir; individual filenames are chosen by the helper (ocr-page-N.png, markdown image names)
Example fix
# before save_ocr_result_resources(result, '/data/out/pages.zip') # existing file # after save_ocr_result_resources(result, '/data/out/pages') # existing directory
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
p = Path(destination)
if p.exists() and not p.is_dir():
raise ValueError(f'{destination} is a file; pass a directory')
p.mkdir(parents=True, exist_ok=True) Type guard
def is_directory(p: str) -> bool:
from pathlib import Path
return Path(p).is_dir() Try / catch
try:
save_ocr_result_resources(result, dest)
except InvalidRequestError as e:
if 'existing directory' in str(e):
raise ValueError(f'pass the output directory, not a file: {e}') from e
raise Prevention
- Adopt a convention: batch save helpers take directories, save_resource takes a full target path
- Never reuse a save_resource destination string for the batch helpers
When it happens
Trigger: save_ocr_result_resources(result, 'results.tar') where results.tar is a file; destination points at a symlink to a file; a previously-created output placeholder file shares the intended directory name.
Common situations: Caller passes a full file path (copied from a save_resource call) instead of the directory; a file was accidentally created where the output directory should be; config value mixes up dir and file semantics.
Related errors
- File not found: ${path}
- destination is required.
- Destination parent must be a directory: {parent}
- {destination}
- File not found: {file_path}
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/5406bbf6a21aba4b.
Report an issue: GitHub.