HKUDS/DeepTutor · error · MinerUError
MinerU archive has too many entries ({len(members)}).
Error message
MinerU archive has too many entries ({len(members)}). What it means
The downloaded result zip contains more than _MAX_ENTRIES non-directory members, so extraction is refused as a zip-bomb guard.
Source
Thrown at deeptutor/services/parsing/engines/mineru/cloud.py:334
import shutil
shutil.rmtree(path)
path.mkdir(parents=True, exist_ok=True)
def _extract_archive(archive_bytes: bytes, target_dir: Path) -> None:
"""Extract the MinerU zip into ``target_dir``, preserving its directory
tree (the ``images/`` subdir matters) while defending against Zip Slip and
zip bombs. Unlike :func:`safe_extract_zip`, this keeps subdirectories and
does not apply a document-extension whitelist — the archive is a trusted
MinerU artifact, not a user upload."""
target_root = target_dir.resolve()
total = 0
try:
with zipfile.ZipFile(io.BytesIO(archive_bytes)) as archive:
members = [m for m in archive.infolist() if not m.is_dir()]
if len(members) > _MAX_ENTRIES:
raise MinerUError(f"MinerU archive has too many entries ({len(members)}).")
for member in members:
# Collapse to a POSIX-relative path and reject traversal.
rel = Path(member.filename.replace("\\", "/"))
if rel.is_absolute() or ".." in rel.parts:
logger.warning("Skipping unsafe zip member: %s", member.filename)
continue
dest = (target_root / rel).resolve()
if target_root not in dest.parents and dest != target_root:
logger.warning("Skipping zip member escaping root: %s", member.filename)
continue
total += member.file_size
if total > _MAX_TOTAL_BYTES:
raise MinerUError("MinerU archive exceeds the size limit.")
dest.parent.mkdir(parents=True, exist_ok=True)
with archive.open(member) as src, open(dest, "wb") as out:
out.write(src.read())
except zipfile.BadZipFile as exc:
raise MinerUError(f"MinerU returned an invalid archive: {exc}") from excView on GitHub (pinned to 3e82f13042)
Solutions
- If legitimate: split the source PDF and parse in parts.
- Re-download (retry) in case of corruption.
- Raise _MAX_ENTRIES if you control the deployment and trust the source.
- Check the PDF for corruption/oddities.
Defensive patterns
Strategy: validation
Validate before calling
import io, zipfile
def archive_safe(data: bytes, max_entries: int) -> bool:
with zipfile.ZipFile(io.BytesIO(data)) as z:
return sum(1 for m in z.infolist() if not m.is_dir()) <= max_entries Try / catch
except MinerUError as e:
if "too many entries" in str(e):
split_pdf_and_reparse(pdf) Prevention
- Split very large PDFs before cloud parsing.
- Retry once in case of a corrupted download.
- Treat the cap as a zip-bomb guard — don't disable it blindly.
When it happens
Trigger: A result archive (legitimately huge doc or malicious/corrupt zip) whose member count exceeds _MAX_ENTRIES.
Common situations: Parsing a massive PDF producing thousands of artifact files; a corrupted download inflating the archive; pathological documents emitting per-glyph files.
Related errors
- Invalid math animator config: {details}
- Rejected archive '{sanitized_filename}': {exc}
- MinerU cloud mode is selected but no API token is configured
- PDF file not found: {pdf_path}
- MinerU API did not return an upload URL (missing batch_id/fi
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/f2e292b906a86e4e.
Report an issue: GitHub.