PaddlePaddle/PaddleOCR · error · ResponseFormatError
Expected a JSON response body.
Error message
Expected a JSON response body.
What it means
ResponseFormatError with 'Expected a JSON response body.' means the HTTP request itself succeeded but resp.json() threw while decoding the body — the server returned an empty body or content that is not JSON (HTML, plain text, binary). The underlying decode error is preserved on `cause`. It comes from the private fetchJson<T>() used by most JSON API endpoints.
Source
Thrown at api_sdk/typescript/src/internal/http.ts:167
async fetchResource(url: string, signal?: AbortSignal, timeoutMs?: number): Promise<ArrayBuffer> {
const resp = await this.fetch(url, { method: "GET" }, signal, false, timeoutMs);
return resp.arrayBuffer();
}
private async fetchJson<T>(
url: string,
init: RequestInit,
signal?: AbortSignal,
withAuth: boolean = true,
timeoutMs?: number,
): Promise<T> {
const resp = await this.fetch(url, init, signal, withAuth, timeoutMs);
let payload: APIResponse<T>;
try {
payload = await resp.json() as APIResponse<T>;
} catch (error) {
throw new ResponseFormatError("Expected a JSON response body.", { cause: error });
}
if (payload.code !== undefined && payload.code !== 0) {
throw new APIError(resp.status, payload.msg || "PaddleOCR official API request failed.");
}
if (!payload || typeof payload !== "object" || !("data" in payload)) {
throw new ResponseFormatError("Response body is missing data.");
}
return payload.data;
}
private async fetch(
url: string,
init: RequestInit,
signal?: AbortSignal,
withAuth: boolean = true,
timeoutMs?: number,
): Promise<Response> {
const headers: Record<string, string> = {View on GitHub (pinned to 2661c7c0ef)
Solutions
- Log the actual body: catch the error and print e.cause plus re-run the request with the same headers via curl to see what the server really returned
- Verify the API base URL / endpoint configuration — the most common cause is hitting a host that serves HTML
- If a proxy or VPN sits between you and the API, exempt the API host or verify it does not rewrite responses
- If persistent and reproducible with curl, treat it as a service-side regression and report it with the request ID
Example fix
try {
const status = await client.getJobStatus(jobId);
} catch (e) {
if (e instanceof ResponseFormatError && /Expected a JSON/.test(e.message)) {
// body was not JSON: dump cause for the raw decode failure
console.error("Non-JSON body from server:", e.cause);
}
} Defensive patterns
Strategy: try-catch
Type guard
async function returnsJsonBody(url: string, init: RequestInit): Promise<boolean> {
const r = await fetch(url, init);
const ct = r.headers.get("content-type") ?? "";
return ct.includes("application/json");
} Try / catch
try {
const status = await poller.getStatus(jobId);
} catch (e) {
if (e instanceof ResponseFormatError && /Expected a JSON response body/.test(e.message)) {
// server sent non-JSON: capture traffic via custom fetchImpl, check base URL
throw new Error(`API returned non-JSON body: ${e.cause}`);
}
throw e;
} Prevention
- Pin the SDK to the documented base URL; never point it at pages that serve HTML
- Wrap fetch with a logging fetchImpl in development to catch contract drift early
- Test against the real API in CI (or a faithful mock returning the full envelope)
When it happens
Trigger: Any authenticated JSON call (submitJson, getJobStatus, getBatchStatus, token fetch) where the gateway responds 2xx with a non-JSON body: an HTML login/consent page, an empty 204, a captive portal, or a WAF block page that still returns 200.
Common situations: Wrong base URL pointing at a marketing page instead of the API host; corporate proxies injecting HTML; misconfigured API key routing the request to a docs page; server-side incidents returning empty bodies; HTTP/2 truncation.
Related errors
- Response body is missing data.
- Token is required. Set PADDLEOCR_ACCESS_TOKEN or pass token
- Destination parent must be a directory: ${parent}
- PaddleOCR official API request failed.
- Request timed out after ${timeoutMs}ms
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/be0d3b34a50457d1.
Report an issue: GitHub.