{"record":{"id":"7bd77a813189cb39","repo":"agentscope-ai/agentscope","slug":"failed-to-parse-filename-r-as-pdf-e","errorCode":null,"errorMessage":"Failed to parse {filename!r} as PDF: {e}","messagePattern":"Failed to parse (.+?) as PDF: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/agentscope/rag/_parser/_pdf.py","lineNumber":78,"sourceCode":"        \"\"\"\n        if isinstance(file, str):\n            with open(file, \"rb\") as fp:\n                file = fp.read()\n\n        try:\n            from pypdf import PdfReader\n            from pypdf.errors import PdfReadError\n        except ImportError as e:\n            raise ImportError(\n                \"Please install pypdf to use the PDF parser. \"\n                \"You can install it by `pip install pypdf` (or \"\n                \"`pip install agentscope[rag]`).\",\n            ) from e\n\n        try:\n            reader = PdfReader(io.BytesIO(file))\n        except PdfReadError as e:\n            raise ValueError(\n                f\"Failed to parse {filename!r} as PDF: {e}\",\n            ) from e\n\n        sections: list[Section] = []\n        for page_idx, page in enumerate(reader.pages, start=1):\n            text = page.extract_text() or \"\"\n            sections.append(\n                Section(\n                    content=TextBlock(text=text),\n                    source=filename,\n                    metadata={\"page\": page_idx},\n                ),\n            )\n        return sections\n","sourceCodeStart":60,"sourceCodeEnd":93,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/rag/_parser/_pdf.py#L60-L93","documentation":"pypdf's PdfReader threw PdfReadError while opening the bytes, meaning the data is not a valid PDF (or is corrupted/encrypted malformed). The parser wraps it in ValueError naming the filename and underlying cause.","triggerScenarios":"Passing a non-PDF file (e.g. a .docx or HTML renamed to .pdf), a truncated download, or a password-protected/corrupt PDF.","commonSituations":"User uploads with wrong extension; interrupted downloads; encrypted PDFs; zero-byte files.","solutions":["Verify the file starts with %PDF- magic bytes and opens in a PDF viewer","Re-download/regenerate the source file if truncated","If the PDF is encrypted, decrypt it first (pikepdf/qpdf) before parsing","Sniff content type before routing to PDFParser instead of trusting extensions"],"exampleFix":"# before\nPDFParser().parse('report.pdf')  # actually HTML\n\n# after\nwith open('report.pdf','rb') as f:\n    head = f.read(5)\nassert head == b'%PDF-', 'not a PDF'  # route to correct parser\nPDFParser().parse('report.pdf')","handlingStrategy":"validation","validationCode":"def is_pdf(data: bytes) -> bool:\n    return data[:5] == b'%PDF-'\n\nif not is_pdf(file_bytes):\n    raise ValueError('file is not a PDF')","typeGuard":"def is_pdf_bytes(data: bytes) -> bool:\n    return isinstance(data, bytes) and data.startswith(b'%PDF-')","tryCatchPattern":"try:\n    parser.parse(path)\nexcept ValueError as e:\n    if 'Failed to parse' not in str(e):\n        raise\n    logger.warning('skipping corrupt PDF %s: %s', path, e)","preventionTips":["Validate magic bytes before parsing","Handle per-file failures gracefully in bulk ingestion","Decrypt password-protected PDFs before parsing"],"tags":["agentscope","rag","pdf","corrupt-file","validation"],"backgroundTag":"corrupt-file-format","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}