PaddlePaddle/PaddleOCR · error · ResponseFormatError

Unknown job state: ${data.state}

Error message

Unknown job state: ${data.state}

What it means

Thrown by normalizeStatus() while polling a job: the status response carried a state field, but its value is not one of the four states this SDK understands ("pending", "running", "done", "failed"). It is a ResponseFormatError, meaning the server reply violated the contract the SDK's poller was built against. This almost always indicates the server and SDK disagree about the job-state enum.

Source

Thrown at api_sdk/typescript/src/internal/poller.ts:117

      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)) {
    throw new ResponseFormatError("Status progress must be an object.");
  }
  return {

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Log the raw HTTP status response body to see the exact state string the server sent
  2. Upgrade the TypeScript SDK to a version that knows the new state value (check changelog for job state additions)
  3. If you control the server, restrict emitted states to pending/running/done/failed until clients are updated
  4. If the new state is terminal-cancel, add server-side mapping to an SDK-known state or expose it via errorMsg on state="failed"

Example fix

// before
const result = await client.waitForResult(jobId); // throws on unknown state

// after
const job = await client.getJob(jobId); // raw status call that tolerates unknown states
if (["pending","running"].includes(job.state)) { /* keep polling via waitForResult */ }
else if (job.state === "done") { /* fetch result */ }
else { /* handle terminal/unknown without the strict poller */ }
Defensive patterns

Strategy: type-guard

Validate before calling

const KNOWN_STATES = new Set(["pending", "running", "done", "failed"]);
const status = await client.getJobStatus(jobId); // raw status call
if (!KNOWN_STATES.has(status.state)) {
  console.warn(`Server reported unknown state ${status.state}; SDK poller would throw`);
}

Type guard

function isKnownJobState(s: string): s is "pending" | "running" | "done" | "failed" {
  return ["pending", "running", "done", "failed"].includes(s);
}

Try / catch

try {
  const result = await poller.wait(jobId);
} catch (e) {
  if (e instanceof ResponseFormatError && /Unknown job state/.test(e.message)) {
    // version skew with server: fetch raw status and decide manually
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the poll/wait API (e.g. waitForResult or whatever drives normalizeStatus) against a server that returns a newer state such as "cancelled", "canceling", "expired", "queued", or a typo'd value like "Done". Also produced by mock/stub servers that invent state names.

Common situations: Server API upgraded to add a cancel/timeout state while the client pins an older SDK; test harness returning hardcoded JSON with a wrong state string; regional deployments with divergent API versions.

Related errors


AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14). Data as JSON: /api/errors/4d31bed3f195a573. Report an issue: GitHub.