{"record":{"id":"1d8e1d1bbe929daf","repo":"PaddlePaddle/PaddleOCR","slug":"batch-response-is-missing-extractresult","errorCode":null,"errorMessage":"Batch response is missing extractResult.","messagePattern":"Batch response is missing extractResult\\.","errorType":"exception","errorClass":"ResponseFormatError","httpStatus":null,"severity":"error","filePath":"api_sdk/typescript/src/internal/poller.ts","lineNumber":69,"sourceCode":"      if (status.state === \"failed\") {\n        throw new JobFailedError(jobId, status.errorMsg || \"Unknown error\");\n      }\n\n      await this.sleep(Math.min(interval, Math.max(0, deadline - Date.now())), signal);\n      interval = Math.min(interval * MULTIPLIER, MAX_INTERVAL);\n    }\n\n    throw new PollTimeoutError(jobId, this.maxWaitTime);\n  }\n\n  async getStatus(jobId: string, signal?: AbortSignal): Promise<JobStatus> {\n    return normalizeStatus(jobId, await this.http.getJobStatus(jobId, signal));\n  }\n\n  async getBatchStatus(batchId: string, signal?: AbortSignal): Promise<BatchStatus> {\n    const data = await this.http.getBatchStatus(batchId, signal);\n    if (!isRecord(data) || !Array.isArray(data.extractResult)) {\n      throw new ResponseFormatError(\"Batch response is missing extractResult.\");\n    }\n    return {\n      batchId,\n      jobs: data.extractResult.map((item) => {\n        if (!isRecord(item) || typeof item.jobId !== \"string\") {\n          throw new ResponseFormatError(\"Batch extractResult item is missing jobId.\");\n        }\n        return normalizeStatus(item.jobId, item);\n      }),\n    };\n  }\n\n  private sleep(ms: number, signal?: AbortSignal): Promise<void> {\n    return new Promise((resolve, reject) => {\n      const timer = setTimeout(resolve, ms);\n      if (!signal) return;\n      signal.addEventListener(\n        \"abort\",","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/api_sdk/typescript/src/internal/poller.ts#L51-L87","documentation":"ResponseFormatError with 'Batch response is missing extractResult.' is thrown by getBatchStatus() when the batch status response's data object is not a record containing an extractResult array. The SDK's batch contract requires data.extractResult to be an array of per-job status objects; its absence means the response shape is not a valid batch status payload.","triggerScenarios":"Calling getBatchStatus(batchId) where batchId is not a real batch (server returns an error-shaped or empty data object with 200), the endpoint version changed the field name, or a mock/stub omits extractResult.","commonSituations":"Passing a jobId instead of a batchId; batch retention expired server-side; SDK/server version drift renaming the field; test doubles returning simplified JSON.","solutions":["Verify you are passing a batchId (returned at batch submission time), not a single jobId","Capture the raw batch status response with a custom fetchImpl to see what data actually contains","Align SDK and server versions — extractResult is part of the batch status contract","Make test mocks return { data: { extractResult: [{ jobId, state, ... }] } }"],"exampleFix":"try {\n  const batch = await poller.getBatchStatus(batchId);\n} catch (e) {\n  if (e instanceof ResponseFormatError && e.message.includes(\"extractResult\")) {\n    logger.error(\"Not a valid batch response for\", batchId);\n  }\n}","handlingStrategy":"validation","validationCode":"const BATCH_ID_RE = /^batch-[\\w-]+$/; // adjust to your server's format\nfunction isPlausibleBatchId(id: string): boolean {\n  return BATCH_ID_RE.test(id);\n}","typeGuard":"function isBatchResponse(v: unknown): v is { extractResult: unknown[] } {\n  return typeof v === \"object\" && v !== null && Array.isArray((v as any).extractResult);\n}","tryCatchPattern":"try {\n  const batch = await poller.getBatchStatus(batchId);\n} catch (e) {\n  if (e instanceof ResponseFormatError && e.message.includes(\"extractResult\")) {\n    // not retryable as-is: verify batchId provenance and API version\n    throw new Error(`batchId '${batchId}' did not return a batch payload`);\n  }\n  throw e;\n}","preventionTips":["Keep batchIds from submission separate from jobIds in your types to prevent mix-ups","Contract-test batch endpoints after server upgrades","Return the full extractResult array from test doubles"],"tags":["response-format","batch","contract","typescript"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}