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
- 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
- Read the embedded body text — it usually names the real problem even for unmapped statuses
- For 404s on old jobIds, design your pipeline to consume results promptly or re-submit
- 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
- Branch on e.statusCode: 4xx (except 408/429) is permanent, 5xx/408 is retryable
- Consume results promptly; do not rely on jobIds surviving long retention windows
- Compress or split uploads to stay under gateway body limits
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
- PaddleOCR official API request failed.
- Expected a JSON response body.
- Response body is missing data.
- Request timed out after ${timeoutMs}ms
- Authentication failed: ${text}
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/b998db642da4d626.
Report an issue: GitHub.