opendatalab/MinerU · error · ValueError

Legacy binary PPT files are not supported; convert the file

Error message

Legacy binary PPT files are not supported; convert the file to PPTX before parsing.

What it means

normalize_pptx_package rejects legacy binary PowerPoint files by magic number (the OLE2 compound-document signature, D0 CF 11 E0 ...). python-pptx can only read the OOXML zip format (.pptx), so .ppt files from PowerPoint 97-2003 fail immediately with a clear message instead of a confusing downstream parse error.

Source

Thrown at mineru/model/pptx/package_normalizer.py:92

    (
        b"http://purl.oclc.org/ooxml/officeDocument/docPropsVTypes",
        b"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes",
    ),
    (
        b"http://purl.oclc.org/ooxml/officeDocument/oleObject",
        b"http://schemas.openxmlformats.org/officeDocument/2006/oleObject",
    ),
)

KNOWN_NAMESPACE_DECLARATIONS = {
    b"w": f'xmlns:w="{WORDPROCESSINGML_NS}"'.encode("utf-8"),
}


def normalize_pptx_package(file_bytes: bytes) -> bytes:
    """在进入 python-pptx 前修复常见包级兼容问题,避免修复逻辑散落到形状解析阶段。"""
    if file_bytes.startswith(LEGACY_PPT_MAGIC):
        raise ValueError(
            "Legacy binary PPT files are not supported; convert the file to PPTX before parsing."
        )

    try:
        with ZipFile(BytesIO(file_bytes)) as source:
            loaded_members: list[tuple[ZipInfo, bytes]] = []
            rewritten_members: list[tuple[ZipInfo, bytes]] = []
            skipped_members: set[str] = set()
            changed = False

            for info in source.infolist():
                member_data = _read_member_best_effort(source, info)
                if member_data is None:
                    skipped_members.add(info.filename)
                    changed = True
                    continue
                loaded_members.append((info, member_data))

View on GitHub (pinned to 4fe4bde114)

Solutions

  1. Convert the file to real PPTX with LibreOffice: soffice --headless --convert-to pptx file.ppt.
  2. Detect the format upstream by magic bytes, not extension, and route legacy files to a converter.
  3. Re-export from the source application in Office 2007+ format.

Example fix

# before
result = parse_pptx(open('deck.ppt','rb').read())

# after
subprocess.run(['soffice','--headless','--convert-to','pptx','deck.ppt'])
result = parse_pptx(open('deck.pptx','rb').read())
Defensive patterns

Strategy: validation

Validate before calling

LEGACY = bytes.fromhex('d0cf11e0a1b11ae1')
def is_legacy_ppt(data: bytes) -> bool:
    return data[:8] == LEGACY

Try / catch

try:
    normalized = normalize_pptx_package(data)
except ValueError as e:
    if 'Legacy binary PPT' in str(e):
        raise ValueError('convert with: soffice --headless --convert-to pptx <file>') from e
    raise

Prevention

When it happens

Trigger: Feeding a .ppt (or any OLE2 container like some .doc/.xls) file to the PPTX parsing pipeline; often happens because the file was renamed to .pptx without conversion.

Common situations: Users renaming instead of converting, scanned/exported documents saved in compatibility mode, or content-disposition pipelines that route by extension while the bytes are legacy format.

Related errors


AI-assisted analysis of opendatalab/MinerU@4fe4bde114 (2026-08-14). Data as JSON: /api/errors/f5410f9d13208609. Report an issue: GitHub.