PaddlePaddle/PaddleOCR · error · ResponseFormatError
Status response is missing state.
Error message
Status response is missing state.
What it means
ResponseFormatError with 'Status response is missing state.' is thrown by normalizeStatus() when a job status payload's data object is not a record containing a string `state` field. Every getJobStatus/getStatus and every batch extractResult entry must carry a state string ('pending' | 'running' | 'done' | 'failed'); without it the SDK cannot classify the job.
Source
Thrown at api_sdk/typescript/src/internal/poller.ts:114
private async withPollTimeout<T>(jobId: string, remainingMs: number, operation: () => Promise<T>): Promise<T> {
if (remainingMs <= 0) {
throw new PollTimeoutError(jobId, this.maxWaitTime);
}
try {
return await operation();
} catch (error) {
if (error instanceof RequestTimeoutError && error.timeoutMs === remainingMs) {
throw new PollTimeoutError(jobId, this.maxWaitTime, { cause: error });
}
throw error;
}
}
}
function normalizeStatus(jobId: string, data: unknown): JobStatus {
if (!isRecord(data) || typeof data.state !== "string") {
throw new ResponseFormatError("Status response is missing state.");
}
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)) {View on GitHub (pinned to 2661c7c0ef)
Solutions
- Verify the jobId is the exact non-empty string returned by submit (see error 32) and has not expired
- Capture the raw status response with a custom fetchImpl to inspect the data object
- Upgrade the SDK to match the deployed API version — state is part of the status contract
- Fix stubs to include state: 'pending' in every status payload
Example fix
try {
const status = await poller.getStatus(jobId);
} catch (e) {
if (e instanceof ResponseFormatError && e.message.includes("state")) {
logger.error("Status payload unusable for job", jobId);
// do not loop: contract is broken or the id is invalid
}
} Defensive patterns
Strategy: type-guard
Validate before calling
const VALID_STATES = ["pending", "running", "done", "failed"] as const;
function isValidStatePayload(data: unknown): boolean {
return typeof data === "object" && data !== null
&& typeof (data as any).state === "string"
&& (VALID_STATES as readonly string[]).includes((data as any).state);
} Type guard
function isJobStatusPayload(v: unknown): v is { state: string } {
return typeof v === "object" && v !== null && typeof (v as { state?: unknown }).state === "string";
} Try / catch
try {
const status = await poller.getStatus(jobId);
} catch (e) {
if (e instanceof ResponseFormatError && e.message.includes("state")) {
// payload unusable: stop polling this id and surface the contract break
throw new Error(`Status payload for ${jobId} has no state — wrong id or API drift`);
}
throw e;
} Prevention
- Store jobIds as opaque strings exactly as returned; never reconstruct or truncate them
- Add a status-payload contract test (state field present and one of the four values) to CI
- Upgrade SDK and server together; the state field name is part of the contract
When it happens
Trigger: Polling getStatus(jobId) or the internal getJobStatus where the server returns a data object without state — e.g. the jobId is unknown and the server answers 200 with an error-shaped body, a field rename in a newer API, or batch entries for jobs not yet registered.
Common situations: Passing an invalid or expired jobId; SDK version behind a server-side contract change (state renamed to status); mocks returning partial objects; middleware returning { data: { msg: ... } } on soft errors.
Related errors
- Response body is missing data.
- Submit response is missing jobId.
- Batch response is missing extractResult.
- Batch extractResult item is missing jobId.
- Expected a JSON response body.
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/055d52239a68eedf.
Report an issue: GitHub.