PaddlePaddle/PaddleOCR · error · ResultParseError

Malformed document parsing result payload

Error message

Malformed document parsing result payload: {e}

What it means

ResultParseError raised while converting downloaded JSONL into a DocParsingResult (PP-StructureV3 / document parsing): a KeyError or TypeError hit the expected structure ('result', 'layoutParsingResults', per-item 'markdown', 'markdown.images', 'exports', etc.). The chained exception identifies the exact missing key or wrong type.

Solutions

  1. Dump the raw JSONL lines and verify each expected key ('result', 'layoutParsingResults', item['markdown']) exists before parsing
  2. Match client version to server version; pin the version pair that works
  3. Ensure the job was actually a document-parsing job — use the OCR path for OCR jobs
  4. If the schema legitimately changed, extend the parser locally or open an issue with the raw payload attached

Example fix

# before
result = parse_doc_parsing_result(job_id, jsonl)  # KeyError('markdown')

# after
for line in jsonl:
    item = line['result']['layoutParsingResults'][0]
    assert 'markdown' in item, f"unexpected schema: {sorted(item)}"
result = parse_doc_parsing_result(job_id, jsonl)
Defensive patterns

Strategy: try-catch

Validate before calling

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

Type guard

def is_doc_parsing_payload(obj: object) -> bool:
    if not isinstance(obj, list) or not obj:
        return False
    r = obj[0].get('result') if isinstance(obj[0], dict) else None
    items = r.get('layoutParsingResults') if isinstance(r, dict) else None
    return bool(items) and isinstance(items[0], dict) and 'markdown' in items[0]

Try / catch

try:
    result = parse_doc_parsing_result(job_id, jsonl_data)
except ResultParseError as e:
    logger.error("doc result schema mismatch for %s: %s", job_id, e)
    raise

Prevention

When it happens

Trigger: parse_doc_parsing_result(job_id, jsonl_data) raises when a line lacks 'result', 'layoutParsingResults' is missing/not a list, an item lacks 'markdown', or markdown/images entries have unexpected types. Happens when the server's document-parsing schema differs from the client's expectations or a plain-OCR result is fed to the document parser.

Common situations: Version skew between client and PaddleOCR server on the PP-StructureV3 result format; calling the doc-parsing parse path on a plain OCR job's output; server returning an error line inside the JSONL; renamed fields (e.g. markdown.images key changes) after a server upgrade.

Understand the failure class

Related errors


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

Appendix: source

Thrown at paddleocr/_api_client/_poller.py:152

                pages.append(
                    DocParsingPage(
                        markdown_text=markdown["text"],
                        markdown_images=markdown.get("images", {}),
                        output_images=item.get("outputImages", {}),
                        pruned_result=item.get("prunedResult"),
                        input_image_url=item.get("inputImage"),
                        exports=item.get("exports", {}),
                        markdown=markdown,
                        raw=item,
                    )
                )
        return DocParsingResult(
            job_id=job_id,
            pages=pages,
            data_info=data_info,
        )
    except (KeyError, TypeError) as e:
        raise ResultParseError(f"Malformed document parsing result payload: {e}") from e

View on GitHub (pinned to 2661c7c0ef)