PaddlePaddle/PaddleOCR · error · InvalidRequestError
resourceUrl is required.
Error message
resourceUrl is required.
What it means
Thrown by validate_result_json_url in paddleocr/_api_client/_core.py:186 when a completed (state 'done') job's data does not contain an object 'resultUrl'. For done jobs the SDK needs resultUrl.jsonUrl to download the JSONL results. A missing or non-object resultUrl means the server violated the documented done-job schema. It is a ResponseFormatError raised during result retrieval, not during submission.
Source
Thrown at api_sdk/typescript/src/client.ts:125
async saveOcrResultResources(
result: OCRResult,
destination: string,
options: SaveResourceOptions = {},
): Promise<string[]> {
return this.saveResultResources(result, destination, options);
}
async saveDocumentParsingResultResources(
result: DocParsingResult,
destination: string,
options: SaveResourceOptions = {},
): Promise<string[]> {
return this.saveResultResources(result, destination, options);
}
private async saveResourceUrl(resourceUrl: string, destination: string, options: SaveResourceOptions): Promise<string> {
if (!resourceUrl) {
throw new InvalidRequestError("resourceUrl is required.");
}
let url: URL;
try {
url = new URL(resourceUrl);
} catch (error) {
throw new InvalidRequestError(`Invalid resource URL: ${resourceUrl}`, { cause: error });
}
const target = await this.resolveDestination(url, destination, options);
const content = await this.http.fetchResource(resourceUrl);
await writeFile(target, Buffer.from(content), { flag: options.overwrite ? "w" : "wx" });
return target;
}
private async saveResultResources(
result: OCRResult | DocParsingResult,
destination: string,
options: SaveResourceOptions,
): Promise<string[]> {View on GitHub (pinned to 2661c7c0ef)
Solutions
- Inspect the raw job status JSON (get_job_status output) to see the shape of data.resultUrl
- Retry the get_result call once — transient server-side serialization bugs can produce malformed done responses
- Upgrade the paddleocr SDK in case the resultUrl schema changed and the SDK was updated for it
- If the job's artifacts expired (old jobId), resubmit the document to create a fresh job
Defensive patterns
Strategy: try-catch
Validate before calling
status = client.get_job_status(job_id)
if status.get("state") == "done" and not isinstance(status.get("resultUrl"), dict):
logger.warning("Job done but resultUrl missing; retrying status fetch") Type guard
def has_result_url(data: dict) -> bool:
return isinstance(data.get("resultUrl"), dict) Try / catch
from paddleocr._api_client.errors import ResponseFormatError
try:
result = client.get_result(job_id)
except ResponseFormatError as e:
if "resultUrl" in str(e):
time.sleep(5) # artifact may still be settling
result = client.get_result(job_id) Prevention
- Poll until state is 'done' before fetching results
- Add a short delay between done and get_result for very fresh jobs
- Report persistent malformed done responses with the raw payload
When it happens
Trigger: Calling client.get_result() (or any path that validates a done job response) where the job status response's data lacks resultUrl or has it as a string/null instead of an object with jsonUrl.
Common situations: Server-side change to the result URL structure; a done job whose artifacts expired or were cleaned up; a partially-initialized job marked done without results; API version mismatch between SDK and server.
Related errors
- Model ${model} is not a document parsing model.
- Invalid resource URL: ${resourceUrl}
- Destination already exists: ${target}
- Token is required. Set PADDLEOCR_ACCESS_TOKEN or pass token
- File not found: ${path}
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/9404e656148def17.
Report an issue: GitHub.