PaddlePaddle/PaddleOCR · error · AuthError
Token is required. Set PADDLEOCR_ACCESS_TOKEN or pass token
Error message
Token is required. Set PADDLEOCR_ACCESS_TOKEN or pass token option.
What it means
Thrown by unwrap_api_response in paddleocr/_api_client/_core.py:170 when a 2xx API response's JSON envelope has no object 'data' field. The PaddleOCR API contract wraps every payload as {code, msg, data}; after the code check passes, 'data' must be a JSON object. A missing, null, list, or scalar 'data' triggers this ResponseFormatError. It signals the server response deviated from the documented schema, not a client input problem.
Source
Thrown at api_sdk/typescript/src/client.ts:38
import type { ClientOptions, DocParsingRequest, OCRRequest, SaveResourceOptions } from "./models.js";
import { isDocumentParsingModel, isOCRModel, Model } from "./models.js";
import type { BatchStatus, DocParsingResult, Job, JobStatus, OCRResult } from "./results.js";
const DEFAULT_BASE_URL = "https://paddleocr.aistudio-app.com";
interface ResourceSavePlan {
resourceUrl: string;
filename: string;
}
export class PaddleOCRClient {
private http: HttpClient;
private poller: Poller;
constructor(options: ClientOptions = {}) {
const token = options.token || process.env.PADDLEOCR_ACCESS_TOKEN || "";
if (!token) {
throw new AuthError("Token is required. Set PADDLEOCR_ACCESS_TOKEN or pass token option.");
}
const baseUrl = options.baseUrl || process.env.PADDLEOCR_BASE_URL || DEFAULT_BASE_URL;
const requestTimeout = options.requestTimeout || options.timeout || 300000;
const pollTimeout = options.pollTimeout || options.timeout || 600000;
this.http = new HttpClient(
token,
baseUrl,
requestTimeout,
options.fetch,
options.clientPlatform,
);
this.poller = new Poller(this.http, pollTimeout);
}
async ocr(req: OCRRequest, options?: { signal?: AbortSignal }): Promise<OCRResult> {
const job = await this.submitOcr(req, options);
return this.waitOcrResult(job, options);View on GitHub (pinned to 2661c7c0ef)
Solutions
- Log the raw response body (catch ResponseFormatError and inspect response text via the SDK's http layer or a manual requests call) to see what the server actually returned
- Verify the base URL / API region configured on the client matches the current PaddleOCR API docs
- Check for SDK updates — an envelope change on the server usually gets a matching SDK release
- If a proxy interferes, bypass it or whitelist the API host
- Report the raw payload to PaddleOCR maintainers if the server is genuinely returning an malformed envelope
Example fix
// before
job_id = client.submit_file(...)
// after
from paddleocr._api_client.errors import ResponseFormatError
try:
job_id = client.submit_file(...)
except ResponseFormatError as e:
logger.error("Unexpected API envelope: %s", e)
raise Defensive patterns
Strategy: try-catch
Type guard
def is_api_envelope(payload: object) -> bool:
return isinstance(payload, dict) and isinstance(payload.get("data"), dict) Try / catch
from paddleocr._api_client.errors import ResponseFormatError
try:
result = client.get_job_status(job_id)
except ResponseFormatError as e:
# server broke the envelope contract; capture raw traffic and report
logger.error("Malformed API envelope: %s", e)
raise Prevention
- Pin the SDK version matched to the API version you call
- Log raw request/response pairs in staging to catch envelope drift early
- Route API traffic outside HTML-rewriting proxies
When it happens
Trigger: Any successful call to submit_url/submit_file/get_job_status/get_batch_status where the returned JSON lacks 'data' or has data as a string/list/null — e.g. a proxy or gateway returning {"code":0} with no data, or an API version change that renamed the field.
Common situations: Hitting a different/older API endpoint than the SDK targets; a corporate proxy or WAF rewriting responses; a service version bump changing the envelope; a maintenance page returning 200 with a JSON body without 'data'.
Related errors
- Destination parent must be a directory: ${parent}
- Model ${model} is not a document parsing model.
- File not found: ${path}
- Destination must be an existing directory: ${destination}
- Destination already exists: ${target}
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/3cca3eeffc842f3b.
Report an issue: GitHub.