PaddlePaddle/PaddleOCR · error · ResponseFormatError
Status progress must be an object.
Error message
Status progress must be an object.
What it means
Thrown by normalizeProgress() when a job status response includes an extractProgress field whose value is neither absent/null nor a plain object. The poller tolerates missing progress entirely, but if progress data is present it must be an object with numeric totalPages/extractedPages fields. Any other JSON type (number, string, array, boolean) triggers this ResponseFormatError.
Source
Thrown at api_sdk/typescript/src/internal/poller.ts:133
}
if (!["pending", "running", "done", "failed"].includes(data.state)) {
throw new ResponseFormatError(`Unknown job state: ${data.state}`);
}
return {
jobId,
state: data.state as JobStatus["state"],
progress: normalizeProgress(data.extractProgress),
resultUrl: isRecord(data.resultUrl) ? stringMap(data.resultUrl) : undefined,
errorMsg: typeof data.errorMsg === "string" ? data.errorMsg : undefined,
};
}
function normalizeProgress(progress: unknown): Progress | undefined {
if (progress === undefined || progress === null) {
return undefined;
}
if (!isRecord(progress)) {
throw new ResponseFormatError("Status progress must be an object.");
}
return {
totalPages: typeof progress.totalPages === "number" ? progress.totalPages : 0,
extractedPages: typeof progress.extractedPages === "number" ? progress.extractedPages : 0,
startTime: typeof progress.startTime === "string" ? progress.startTime : undefined,
endTime: typeof progress.endTime === "string" ? progress.endTime : undefined,
};
}
function resultJsonUrl(data: unknown): string {
if (!isRecord(data) || !isRecord(data.resultUrl) || typeof data.resultUrl.jsonUrl !== "string") {
throw new ResponseFormatError("Done job response is missing resultUrl.jsonUrl.");
}
return data.resultUrl.jsonUrl;
}
function stringMap(value: Record<string, unknown>): Record<string, string> {
const result: Record<string, string> = {};View on GitHub (pinned to 2661c7c0ef)
Solutions
- Capture the raw status response and inspect the JSON type of extractProgress
- Fix the server to emit progress as an object { totalPages, extractedPages } or omit it entirely
- Upgrade/align SDK and server versions so both expect the object shape
- If the field is genuinely unused, remove it from the response
Example fix
// before (server response)
{ "state": "running", "extractProgress": 55 }
// after
{ "state": "running", "extractProgress": { "totalPages": 100, "extractedPages": 55 } } Defensive patterns
Strategy: type-guard
Validate before calling
const raw = await client.getJobStatus(jobId);
if (raw.extractProgress != null && typeof raw.extractProgress !== "object") {
// server emits non-object progress; strip it before handing the payload to the poller
delete raw.extractProgress;
} Type guard
function isProgressObject(v: unknown): v is { totalPages?: number; extractedPages?: number } {
return v == null || (typeof v === "object" && !Array.isArray(v));
} Try / catch
try { await poller.wait(jobId); } catch (e) {
if (e instanceof ResponseFormatError && /progress must be an object/.test(e.message)) {
// server-side serialization bug: report to API owner, fall back to non-progress polling
} else throw e;
} Prevention
- Contract-test the status endpoint shape (extractProgress is object-or-absent) in CI
- Keep SDK and server versions locked together in deployments
- When changing server progress format, gate it on minimum client version
When it happens
Trigger: Polling a job whose status response contains "extractProgress": 42, "extractProgress": "50%", or "extractProgress": [1,2] instead of an object like {"totalPages":10,"extractedPages":5}. Happens when the server changes progress serialization (e.g. flattening to a percentage number).
Common situations: Server refactor that switched progress from object to scalar percent; partial serialization bugs where progress is emitted as a JSON string; SDK version older than a server progress format change.
Related errors
- Unknown job state: ${data.state}
- Done job response is missing resultUrl.jsonUrl.
- Job ${jobId} failed: ${errorMsg}
- Timed out after ${timeoutMs}ms waiting for job ${jobId}
- Document parsing result item is missing result.layoutParsing
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/3961f1304aef442a.
Report an issue: GitHub.