{"record":{"id":"a6fd85e9e76f1c97","repo":"crewAIInc/crewAI","slug":"pypdf-is-required-for-pdf-chunking","errorCode":null,"errorMessage":"pypdf is required for PDF chunking","messagePattern":"pypdf is required for PDF chunking","errorType":"exception","errorClass":"ProcessingDependencyError","httpStatus":null,"severity":"error","filePath":"lib/crewai-files/src/crewai_files/processing/transformers.py","lineNumber":183,"sourceCode":"    \"\"\"Split a PDF into chunks of maximum page count.\n\n    Yields chunks one at a time to minimize memory usage.\n\n    Args:\n        file: The PDF file to chunk.\n        max_pages: Maximum pages per chunk.\n        overlap_pages: Number of overlapping pages between chunks (for context).\n\n    Yields:\n        PDFFile objects, one per chunk.\n\n    Raises:\n        ProcessingDependencyError: If pypdf is not installed.\n    \"\"\"\n    try:\n        from pypdf import PdfReader, PdfWriter\n    except ImportError as e:\n        raise ProcessingDependencyError(\n            \"pypdf is required for PDF chunking\",\n            dependency=\"pypdf\",\n            install_command=\"pip install pypdf\",\n        ) from e\n\n    content = file.read()\n    reader = PdfReader(io.BytesIO(content))\n    total_pages = len(reader.pages)\n\n    if total_pages <= max_pages:\n        yield file\n        return\n\n    filename = file.filename or \"document.pdf\"\n    base_filename = filename.rsplit(\".\", 1)[0]\n    step = max_pages - overlap_pages\n\n    chunk_num = 0","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-files/src/crewai_files/processing/transformers.py#L165-L201","documentation":"chunk_pdf() lazily imports pypdf (PdfReader/PdfWriter) and raises ProcessingDependencyError('pypdf is required for PDF chunking') with dependency='pypdf' when it is missing. Chunking activates when a PDF has more pages than max_pages (or when FileHandling.CHUNK is selected), so environments without pypdf only fail when a multi-chunk PDF arrives.","triggerScenarios":"Processing a PDF whose page count exceeds max_pages with FileHandling.CHUNK (or calling chunk_pdf directly) while pypdf is not installed. PDFs within the limit yield the original file early and never hit the import.","commonSituations":"Enabling CHUNK handling for large documents after testing only with small PDFs; production image lacking pypdf because it is optional; long reports/manuals (>50 pages) hitting the chunk path for the first time.","solutions":["Install pypdf: pip install pypdf.","Include pypdf in the deployment dependency set whenever CHUNK mode or PDF limits are configured.","Check importlib.util.find_spec('pypdf') at startup and warn/abort early if CHUNK is configured without it.","Alternatively split PDFs upstream before ingestion."],"exampleFix":"# before\n# pypdf not installed; pdf has 120 pages, max_pages=50\nchunks = list(chunk_pdf(pdf_file, max_pages=50))  # ProcessingDependencyError\n\n# after\n# shell: pip install pypdf\nchunks = list(chunk_pdf(pdf_file, max_pages=50))","handlingStrategy":"validation","validationCode":"import importlib.util\n\nif importlib.util.find_spec(\"pypdf\") is None and handling == FileHandling.CHUNK:\n    raise RuntimeError(\"PDF chunking requires pypdf: pip install pypdf\")","typeGuard":null,"tryCatchPattern":"from crewai_files.processing.exceptions import ProcessingDependencyError\n\ntry:\n    chunks = list(chunk_pdf(pdf_file, max_pages=50))\nexcept ProcessingDependencyError as e:\n    if e.dependency == \"pypdf\":\n        raise RuntimeError(f\"missing optional dependency; run: {e.install_command}\") from e\n    raise","preventionTips":["Install pypdf wherever CHUNK mode or max_pages constraints exist.","Verify optional imports at startup when the corresponding handling mode is configured.","Test the chunking path with a multi-chunk-sized PDF, not just small files."],"tags":["pypdf","dependency","pdf","chunking","optional-dependency"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}