PaddlePaddle/PaddleOCR · error · InvalidRequestError
Destination parent must be a directory: ${parent}
Error message
Destination parent must be a directory: ${parent} What it means
Raised as ResponseFormatError by _response_json in paddleocr/_api_client/_http.py:62 when the body parses as JSON but the top-level value is not an object — e.g. a JSON array, string, number, or null. The API envelope must be an object ({code, msg, data}); anything else cannot be unwrapped. Distinguished from error 167 (unparseable body): here the JSON is valid but wrongly shaped.
Source
Thrown at api_sdk/typescript/src/client.ts:235
}
seen.add(target);
}
}
private async resolveDestination(url: URL, destination: string, options: SaveResourceOptions): Promise<string> {
let destinationStat;
try {
destinationStat = await stat(destination);
} catch {
destinationStat = undefined;
}
const target = destinationStat?.isDirectory() ? join(destination, safeUrlBasename(url)) : destination;
await this.requireWritableTarget(target, options);
const parent = dirname(target);
try {
const parentStat = await stat(parent);
if (!parentStat.isDirectory()) {
throw new InvalidRequestError(`Destination parent must be a directory: ${parent}`);
}
} catch (error) {
if (error instanceof InvalidRequestError) {
throw error;
}
throw new FileNotFoundError(parent, { cause: error });
}
return target;
}
private async submit(
model: string,
task: Job["task"],
req: { fileUrl?: string; filePath?: string; pageRanges?: string; batchId?: string; options?: object },
signal?: AbortSignal,
): Promise<string> {
if (!req.fileUrl && !req.filePath) {
throw new InvalidRequestError("Either fileUrl or filePath is required.");View on GitHub (pinned to 2661c7c0ef)
Solutions
- Inspect the parsed top-level type of the response body
- Check the request URL against current API docs — an array top-level usually means a different resource endpoint
- Fix mock servers/fixtures to return an object envelope
- Upgrade the SDK if the API envelope changed
Defensive patterns
Strategy: type-guard
Type guard
def is_json_object_body(response) -> bool:
try:
return isinstance(response.json(), dict)
except ValueError:
return False Try / catch
from paddleocr._api_client.errors import ResponseFormatError
try:
status = client.get_job_status(job_id)
except ResponseFormatError as e:
if "must be a JSON object" in str(e):
logger.error("API returned a non-object JSON top level; check endpoint/SDK versions")
raise Prevention
- Contract-test that API responses are object-shaped at the top level
- Keep mock servers envelope-accurate
When it happens
Trigger: An endpoint returning a bare JSON array (e.g. a list of jobs) or a JSON string literal with 2xx status, on submit/status/batch calls routed through _response_json.
Common situations: Wrong endpoint or API version returning a different top-level shape; a mock server returning arrays; middleware wrapping/unwrapping payloads; test fixtures with incorrect structure.
Related errors
- Token is required. Set PADDLEOCR_ACCESS_TOKEN or pass token
- Model ${model} is not a document parsing model.
- File not found: ${path}
- Destination must be an existing directory: ${destination}
- Destination already exists: ${target}
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/53beb0104f0ad844.
Report an issue: GitHub.