PaddlePaddle/PaddleOCR · error · ResultParseError

Malformed OCR result payload: {e}

Error message

Malformed OCR result payload: {e}

What it means

ResultParseError raised while converting the downloaded JSONL into an OCRResult: a KeyError or TypeError occurred accessing the expected structure (each line's 'result' dict, 'layoutParsingResults' list, per-page keys, prunedResult, etc.). The chained exception names the exact missing key or bad type.

Source

Thrown at paddleocr/_api_client/_poller.py:121

            if isinstance(result.get("dataInfo"), dict):
                data_info.update(result["dataInfo"])
            for item in result["ocrResults"]:
                pages.append(
                    OCRPage(
                        pruned_result=item["prunedResult"],
                        ocr_image_url=item.get("ocrImage"),
                        doc_preprocessing_image_url=item.get("docPreprocessingImage"),
                        input_image_url=item.get("inputImage"),
                        raw=item,
                    )
                )
        return OCRResult(
            job_id=job_id,
            pages=pages,
            data_info=data_info,
        )
    except (KeyError, TypeError) as e:
        raise ResultParseError(f"Malformed OCR result payload: {e}") from e


def parse_doc_parsing_result(job_id: str, jsonl_data: list) -> DocParsingResult:
    try:
        pages = []
        data_info = {}
        for line_obj in jsonl_data:
            result = line_obj["result"]
            if isinstance(result.get("dataInfo"), dict):
                data_info.update(result["dataInfo"])
            for item in result["layoutParsingResults"]:
                markdown = item["markdown"]
                pages.append(
                    DocParsingPage(
                        markdown_text=markdown["text"],
                        markdown_images=markdown.get("images", {}),
                        output_images=item.get("outputImages", {}),
                        pruned_result=item.get("prunedResult"),

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Inspect the raw JSONL (it is available on the exception path — dump it before parsing) and compare keys against what parse_ocr_result expects
  2. Align client and server versions so the result schema matches
  3. If you submitted via a document-parsing endpoint, use the document-parsing flow / parse_doc_parsing_result instead of the OCR flow
  4. Report/patch the parser if the server legitimately renamed a key, and pin the working version until then

Example fix

# before
result = client.ocr(job_id)  # ResultParseError: KeyError('layoutParsingResults')

# after
raw_lines = client._http.fetch_jsonl(json_url)
print(raw_lines)  # inspect actual schema first
result = parse_ocr_result(job_id, raw_lines)  # then parse with corrected expectations
Defensive patterns

Strategy: try-catch

Validate before calling

def looks_like_ocr_result(jsonl_data) -> bool:
    return bool(jsonl_data) and all(
        isinstance(l, dict) and 'result' in l and 'layoutParsingResults' in l['result']
        for l in jsonl_data
    )

Type guard

def is_ocr_payload(obj: object) -> bool:
    if not isinstance(obj, list) or not obj:
        return False
    first = obj[0]
    return isinstance(first, dict) and isinstance(first.get('result'), dict) \n        and isinstance(first['result'].get('layoutParsingResults'), list)

Try / catch

try:
    result = parse_ocr_result(job_id, jsonl_data)
except ResultParseError as e:
    logger.error("schema mismatch for job %s: %s; raw=%s", job_id, e, jsonl_data)
    raise

Prevention

When it happens

Trigger: parse_ocr_result(job_id, jsonl_data) runs on the fetched JSONL after a 'done' job; it raises when 'result' is missing from a line, 'layoutParsingResults' is absent or not iterable, or a page entry is not a dict / lacks required keys. Typically caused by a server whose result schema differs from what this client version expects.

Common situations: Client library version newer/older than the PaddleOCR server (schema drift, e.g. renamed keys); a doc-parsing (PP-StructureV3) result fed into the OCR parser because the wrong job type/API was called; partial result file where one line has a different shape (e.g. an error-notification line).

Understand the failure class

Related errors


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