{"record":{"id":"7c0a054a508b2fe7","repo":"MadsLorentzen/ai-job-search","slug":"pdf-does-not-exist-pdf-path","errorCode":null,"errorMessage":"PDF does not exist: {pdf_path}","messagePattern":"PDF does not exist: (.+?)","errorType":"exception","errorClass":"VerificationError","httpStatus":null,"severity":"error","filePath":"tools/verify_pdf.py","lineNumber":93,"sourceCode":"    # even when the caller did not request --pages (same Poppler package).\n    pages = parse_page_count(run_tool([\"pdfinfo\", str(pdf_path)]))\n    return text, pages\n\n\ndef extract_text_layer(pdf_path):\n    \"\"\"Extract ATS-readable text. Returns (text, pages, extractor_name).\"\"\"\n    pypdf_result = _extract_pypdf(pdf_path)\n    if pypdf_result is not None:\n        text, pages = pypdf_result\n        return text, pages, \"pypdf\"\n    text, pages = _extract_pdftotext(pdf_path)\n    return text, pages, \"pdftotext\"\n\n\ndef verify_pdf(pdf_path, expected_pages=None, min_chars=1, required_text=(), dump_text=None):\n    pdf_path = Path(pdf_path)\n    if not pdf_path.is_file():\n        raise VerificationError(f\"PDF does not exist: {pdf_path}\")\n\n    extracted_text, actual_pages, extractor = extract_text_layer(pdf_path)\n\n    # Write dump *before* the checks so a failed verification still leaves a .txt\n    if dump_text is not None:\n        dump_path = Path(dump_text)\n        try:\n            dump_path.parent.mkdir(parents=True, exist_ok=True)\n            dump_path.write_text(\n                extracted_text if extracted_text.endswith(\"\\n\") else extracted_text + \"\\n\",\n                encoding=\"utf-8\",\n            )\n        except OSError as exc:\n            raise VerificationError(\n                f\"could not write --dump-text to {dump_path}: {exc}\"\n            ) from exc\n\n    if expected_pages is not None and actual_pages != expected_pages:","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/MadsLorentzen/ai-job-search/blob/79cd383e58f0af7948c7c6462a3a289e9b67421e/tools/verify_pdf.py#L75-L111","documentation":"verify_pdf() raises this when the path argument does not point to an existing regular file. It is an explicit precondition check performed before any text extraction is attempted, so no poppler tools are invoked for a missing file.","triggerScenarios":"Calling verify_pdf('/path/to/missing.pdf') where the path is a typo, a directory, a URL, or the file was deleted/moved before verification. Also triggered when a build pipeline passes an output path that a previous PDF-generation step failed to produce.","commonSituations":"CI job verifying a PDF artifact before the generating step ran or after it failed silently; relative paths resolved against a different working directory; passing a Path versus str mismatch that points elsewhere; file not yet flushed/closed by the producer.","solutions":["Confirm the path exists and is a file: `ls -l <path>` or Path(pdf_path).is_file() before calling","If generated programmatically, check the generation step's exit code/output before verifying","Use absolute paths (e.g. Path.cwd() / relative) to avoid working-directory mismatches","If the file is produced asynchronously, wait/retry until it appears"],"exampleFix":"// before\nverify_pdf('out/report.pdf')\n// after\npdf = Path('out/report.pdf').resolve()\nif not pdf.is_file():\n    raise SystemExit(f'missing artifact: {pdf}')\nverify_pdf(pdf)","handlingStrategy":"validation","validationCode":"from pathlib import Path\np = Path(pdf_path).resolve()\nif not p.is_file():\n    raise SystemExit(f'PDF artifact missing: {p}')\nverify_pdf(p)","typeGuard":null,"tryCatchPattern":"try:\n    verify_pdf(pdf_path)\nexcept VerificationError as e:\n    if 'does not exist' in str(e):\n        # regenerate or locate the artifact\n        ...","preventionTips":["Resolve paths to absolute before verification to avoid cwd drift","Verify artifact-producing steps succeeded before verifying artifacts","Add a pipeline step that fails fast if expected outputs are absent"],"tags":["pdf","file-not-found","precondition","verification","path"],"backgroundTag":null,"analyzedSha":"79cd383e58f0af7948c7c6462a3a289e9b67421e","analyzedAt":"2026-08-27T21:51:12.330Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}