{"record":{"id":"9404e656148def17","repo":"PaddlePaddle/PaddleOCR","slug":"resourceurl-is-required","errorCode":null,"errorMessage":"resourceUrl is required.","messagePattern":"resourceUrl is required\\.","errorType":"exception","errorClass":"InvalidRequestError","httpStatus":null,"severity":"error","filePath":"api_sdk/typescript/src/client.ts","lineNumber":125,"sourceCode":"  async saveOcrResultResources(\n    result: OCRResult,\n    destination: string,\n    options: SaveResourceOptions = {},\n  ): Promise<string[]> {\n    return this.saveResultResources(result, destination, options);\n  }\n\n  async saveDocumentParsingResultResources(\n    result: DocParsingResult,\n    destination: string,\n    options: SaveResourceOptions = {},\n  ): Promise<string[]> {\n    return this.saveResultResources(result, destination, options);\n  }\n\n  private async saveResourceUrl(resourceUrl: string, destination: string, options: SaveResourceOptions): Promise<string> {\n    if (!resourceUrl) {\n      throw new InvalidRequestError(\"resourceUrl is required.\");\n    }\n    let url: URL;\n    try {\n      url = new URL(resourceUrl);\n    } catch (error) {\n      throw new InvalidRequestError(`Invalid resource URL: ${resourceUrl}`, { cause: error });\n    }\n    const target = await this.resolveDestination(url, destination, options);\n    const content = await this.http.fetchResource(resourceUrl);\n    await writeFile(target, Buffer.from(content), { flag: options.overwrite ? \"w\" : \"wx\" });\n    return target;\n  }\n\n  private async saveResultResources(\n    result: OCRResult | DocParsingResult,\n    destination: string,\n    options: SaveResourceOptions,\n  ): Promise<string[]> {","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/api_sdk/typescript/src/client.ts#L107-L143","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"status = client.get_job_status(job_id)\nif status.get(\"state\") == \"done\" and not isinstance(status.get(\"resultUrl\"), dict):\n    logger.warning(\"Job done but resultUrl missing; retrying status fetch\")","typeGuard":"def has_result_url(data: dict) -> bool:\n    return isinstance(data.get(\"resultUrl\"), dict)","tryCatchPattern":"from paddleocr._api_client.errors import ResponseFormatError\ntry:\n    result = client.get_result(job_id)\nexcept ResponseFormatError as e:\n    if \"resultUrl\" in str(e):\n        time.sleep(5)  # artifact may still be settling\n        result = client.get_result(job_id)","preventionTips":["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"],"tags":["api","response-format","result","job"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}