{"record":{"id":"04e2825766fc9381","repo":"datawhalechina/hello-agents","slug":"v1-vision-fallback-pdf","errorCode":null,"errorMessage":"V1 暂不支持 vision_fallback，请先使用文本型 PDF 或手动裁剪目标表格。","messagePattern":"V1 暂不支持 vision_fallback，请先使用文本型 PDF 或手动裁剪目标表格。","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"Co-creation-projects/healer-666-Academic-Data-Agent/src/data_analysis_agent/document_ingestion.py","lineNumber":333,"sourceCode":"        payload = {\n            \"input_kind\": result.input_kind,\n            \"status\": result.status,\n            \"summary\": result.summary,\n            \"normalized_data_path\": result.normalized_data_path.as_posix(),\n            \"duration_ms\": result.duration_ms,\n            \"candidate_table_count\": 0,\n            \"pdf_multi_table_mode\": False,\n            \"mode\": normalized_mode,\n        }\n        log_path.parent.mkdir(parents=True, exist_ok=True)\n        log_path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding=\"utf-8\")\n        return result\n\n    if source_path.suffix.lower() not in SUPPORTED_DOCUMENT_SUFFIXES:\n        raise ValueError(f\"Unsupported input file format: {source_path.suffix}\")\n\n    if normalized_mode == \"vision_fallback\":\n        raise ValueError(\"V1 暂不支持 vision_fallback，请先使用文本型 PDF 或手动裁剪目标表格。\")\n\n    extracted_tables_dir = data_dir / \"extracted_tables\"\n    cleaned_data_path = (data_dir / \"cleaned_data.csv\").resolve()\n    parsed_document_path = (data_dir / \"parsed_document.json\").resolve()\n\n    full_text, records = _extract_pdf_payload(\n        source_path,\n        max_pdf_pages=max_pdf_pages,\n        max_candidate_tables=max_candidate_tables,\n        extracted_tables_dir=extracted_tables_dir,\n    )\n    background_literature_context = _extract_background_context(full_text)\n    requested_table_id = str(selected_table_id or \"\").strip()\n    requested_record = None\n    if requested_table_id:\n        requested_record = next((record for record in records if record.table_id == requested_table_id), None)\n        if requested_record is None:\n            raise ValueError(","sourceCodeStart":315,"sourceCodeEnd":351,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/Co-creation-projects/healer-666-Academic-Data-Agent/src/data_analysis_agent/document_ingestion.py#L315-L351","documentation":"A deliberate scope-limit guard: if the input passes the document-suffix check but mode=='vision_fallback', ingest_document raises ValueError saying V1 does not support vision_fallback and the user should supply a text-based PDF or manually crop the target table. I.e. the mode value is validated (216) but intentionally unimplemented in V1.","triggerScenarios":"Explicitly requesting document_ingestion_mode='vision_fallback' — typically for scanned/image-only PDFs where pdfplumber's text extraction yields nothing usable.","commonSituations":"Users with scanned papers or image-based PDF tables hitting the text-extraction limitation and reaching for the vision mode; client defaults that try vision_fallback automatically on failure.","solutions":["Use mode='auto' (or 'text_only') with a text-based PDF — re-export or OCR the source to embed a text layer.","Manually crop the target table (screenshot/Excel) and supply it as .csv/.xlsx, which takes the tabular path.","OCR the PDF (e.g. ocrmypdf -l eng input.pdf output.pdf) so text extraction works.","Track upstream releases for V2 vision_fallback support."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"import importlib.util\nfrom pathlib import Path\n\ndef ocr_layer_present(pdf_path: Path) -> bool:\n    \"\"\"Heuristic: a text-based PDF extracts characters via pdfplumber.\"\"\"\n    import pdfplumber\n    with pdfplumber.open(pdf_path) as pdf:\n        return any((page.extract_text() or \"\").strip() for page in pdf.pages[:3])\n\nif not ocr_layer_present(Path(pdf_path)):\n    print(\"Scanned PDF: run OCR (ocrmypdf) first; vision_fallback is unsupported in V1\")","typeGuard":null,"tryCatchPattern":"try:\n    result = ingest_document(path, data_dir, logs_dir, mode=\"vision_fallback\")\nexcept ValueError as e:\n    if \"vision_fallback\" in str(e):\n        # fall back: OCR the file, then re-ingest in text mode\n        subprocess.run([\"ocrmypdf\", str(path), str(path)], check=True)\n        result = ingest_document(path, data_dir, logs_dir, mode=\"auto\")\n    else:\n        raise","preventionTips":["Prefer mode='auto'; treat vision_fallback as unavailable in V1.","OCR scanned PDFs (ocrmypdf) so text extraction works.","For image tables, crop manually and provide .csv instead."],"tags":["not-implemented","pdf","ocr","valueerror","document-ingestion","python"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}