PaddlePaddle/PaddleOCR · error · APIError

HTTP ${statusCode}: ${text}

Error message

HTTP ${statusCode}: ${text}

What it means

APIError with 'HTTP <status>: <text>' is the fallback for any non-2xx status not mapped to a specific class (401/403, 400, 429, 503/504 have their own errors). The statusCode property carries the numeric status and the message embeds the best explanation found in the body. Common triggers include 404 (wrong jobId or endpoint), 405, 408, 413 (payload too large), and 500.

Source

Thrown at api_sdk/typescript/src/internal/http.ts:245

    if (resp.ok) return resp;

    let text = await resp.text();
    try {
      const payload = JSON.parse(text) as { msg?: string; message?: string; errorMsg?: string };
      text = payload.msg || payload.message || payload.errorMsg || text;
    } catch {
      // Keep raw response text.
    }
    if (resp.status === 401 || resp.status === 403) {
      throw new AuthError(`Authentication failed: ${text}`);
    } else if (resp.status === 400) {
      throw new InvalidRequestError(`Bad request: ${text}`);
    } else if (resp.status === 429) {
      throw new RateLimitError(`Rate limit exceeded: ${text}`);
    } else if (resp.status === 503 || resp.status === 504) {
      throw new ServiceUnavailableError(resp.status, `Service unavailable: ${text}`);
    } else {
      throw new APIError(resp.status, text);
    }
  }
}

function requireJobId(data: SubmitResponse): string {
  if (!data || typeof data.jobId !== "string" || data.jobId.length === 0) {
    throw new ResponseFormatError("Submit response is missing jobId.");
  }
  return data.jobId;
}

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Branch on e.statusCode: 404 → the jobId/URL is gone (stop retrying, submit a new job); 413 → compress or split the file; 5xx → retry with backoff
  2. Read the embedded body text — it usually names the real problem even for unmapped statuses
  3. For 404s on old jobIds, design your pipeline to consume results promptly or re-submit
  4. Upgrade the SDK if the endpoint shape changed server-side

Example fix

try {
  const result = await poller.waitForResult(jobId);
} catch (e) {
  if (e instanceof APIError) {
    if (e.statusCode === 404) return resubmitJob(jobId);       // expired/unknown job
    if (e.statusCode === 413) throw new Error("File too large");
    if (e.statusCode >= 500) await backoffRetry(() => poller.waitForResult(jobId));
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

function isRetryableStatus(code: number): boolean {
  return code === 408 || code === 429 || code >= 500;
}

Type guard

function isAPIErrorWithStatus(e: unknown): e is APIError & { statusCode: number } {
  return e instanceof APIError && typeof e.statusCode === "number";
}

Try / catch

try {
  const result = await poller.waitForResult(jobId);
} catch (e) {
  if (e instanceof APIError) {
    if (e.statusCode === 404) return resubmit();            // job gone: permanent
    if (e.statusCode === 413) throw new Error("File too large");
    if (e.statusCode >= 500 || e.statusCode === 408) return backoffRetry();
  }
  throw e;
}

Prevention

When it happens

Trigger: Polling or fetching results for a jobId that does not exist or expired server-side (404); uploading a body larger than the gateway limit (413); unexpected server crashes (500); calling an endpoint removed or renamed in a newer API version (404/405).

Common situations: Persisting jobIds in a database and resuming days later after server-side retention expired; oversized PDFs exceeding upload limits; SDK version older than a breaking API change; transient 500s during incidents.

Related errors


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